目录
final修饰的类无法继承。
final修饰的引用一旦指向某个对象,则不能再指向其他对象,但该引用指向的对象内部的数据是可以修改的。编辑
final修饰的实例变量必须手动初始化,因为系统不会赋默认值,强制手动赋值,否则报错
final修饰的实例变量一般和static联合使用,成为常量。
-
final修饰的类无法继承。
final修饰的方法无法覆盖
final修饰的变量只能赋一次值(final修饰的变量无法改变。)
/* final 1、final是java语言中的一个关键字。 2、final表示: 最终的,不可变的。 3、★final修饰的变量 final修饰的局部变量,赋值后不能重新赋值(无法修改) /final修饰的变量只能赋一次值 4、★final修饰的方法 final修饰的方法,在子类中无法被覆盖/重写 5、★final修饰的类 final修饰的类无法被继承 6、final不控制调用,表示被修饰的东西不能改了,与能不能调用没有关系。 */ public class FinalText01 { public static void main(String[] args) { //局部变量 int i = 100; final int k = 200; //重新赋值 i = 200; //Error: 无法为最终变量k分配值 //k = 2000; final修饰的变量赋值后不能再修改值 final int l; //第一次赋值 l = 1; //重新赋值 //l = 11; //编译报错:Error: 可能已分配变量l } } //class A2{} final class A2{} //A2不能有子孙(不能有子类),相当于绝育了。 /* B2类可以继承A2类,等于对A2类的功能进行扩展,如果不希望别人对A2类进行扩展,可以为A2加final关键字 这样其他类就无法继承A2类了。 错误: java: 无法从最终A2进行继承 */ //class B2 extends A2{} //Error: 无法从最终java.lang.String进行继承,String类前有final修饰, //class MyString extends String{} class C{ public final void doSome(){ System.out.println("C doSome"); } } class D extends C{ /* Error: D中的doSome()无法覆盖C中的doSome() 被覆盖的方法为final public void doSome(){ System.out.println("D doSome"); } */ }
-
final修饰的引用一旦指向某个对象,则不能再指向其他对象,但该引用指向的对象内部的数据是可以修改的。
/* final修饰的变量,如果这个变量是一个“引用”会怎么样? 注意:final修饰的变量只能赋一次值(万变不离其宗) “引用”实际上保存的是一个对象的“内存地址”,加上final之后,表示:这个“引用”保存的“内存地址”不可以再改变 final修饰的“引用” : 该引用只能指向一个对象,并且永远只指向该对象,无法再指向其他对象。 并且在该方法执行过程中,该引用指向对象之后,该对象不会被垃圾回收器回收 直到main方法结束之后,才会释放空间。 虽然final的引用指向对象A之后,不能再重新指向对象B。但是对象A内部的数据可以被修改。 */ public class FinalText02 { public static void main(String[] args) { //这里的p1、p2在main方法中,实际上也是一个局部变量。 //创建对象 Person1 p1 = new Person1(10); System.out.println(p1.age); //修改 p1 = new Person1(20); System.out.println(p1.age); //final修饰的引用 final Person1 p2 = new Person1(30); //重新赋值(重新分配一个内存地址) 编译报错:Error: 无法为最终变量p2分配值 //p2 = new Person1(30); //可以为p2赋一个null吗? 编译爆错:Error: 无法为最终变量p2分配值 //p2 = null; //虽然不再指向其他对象,但是对象中保存的数据可以修改。 p2.age = 88; System.out.println(p2.age); } } class Person1{ int age; public Person1(){ } public Person1(int age){ this.age = age; } }
-
final修饰的实例变量必须手动初始化,因为系统不会赋默认值,强制手动赋值,否则报错
/* ★ final修饰的变量只能赋值一次。 实例变量如果没有手动赋值,系统会赋默认值 final 修饰的实例变量 经过测试: 结论:final修饰的实例变量,系统不会再赋默认值,要求程序员必须手动赋值。 在定义实际变量时在后面直接赋值可以 :final int i =10; 在构造方法中赋值也可以: final int i; 无参: public User(){ this.i = 10; } 有参: public User(int i){ this.i = i; } ★这两个构造方法有一个即可,共存也可以的。调用时: 调用无参的,该对象的i值就是:10 调用有参的,该对象的i值是调用时传递进去的i值。 ★虽然系统赋默认值是:0/0.0/null等,但是不意味着这些值不可以赋值给变量 不手动赋值,等系统赋默认值,实际报错:Error: 变量 weight 未在默认构造器中初始化 也就是说系统实际上不会为final修饰的实例变量赋默认值,同时强制手动赋值。 */ public class FinalText03 { public static void main(String[] args) { User u = new User(60); System.out.println(u.weight); } } class User{ //final修饰的实例变量 //编译报错:Error: 变量 age 未在默认构造器中初始化 //final int age; //结论:final修饰的实例变量,系统不会再赋默认值,要求程序员必须手动赋值。 //编译通过,因为这里手动赋值了。 final double height =1.8 ; //如果定义的时候不赋值,可以在无参的构造方法里手动为它赋值。 //因为系统赋默认值的时候是在构造方法执行时赋值,所以只要赶在系统赋默认值之前为final修饰的变量赋值就可以 //但是不能等系统赋默认值,因为系统看到你用final修饰了实例变量之后,不再为变量赋默认值的同时强制手动赋值。 // 如果构造方法里不手动赋值,就会报错:weight 未在默认构造器中初始化 final double weight; //构造方法 public User(){ this.weight = 60; } //有参构造 public User(double weight){ this.weight = weight;//这个也算是赋值了,没有采用系统默认值。在调用此有参构造方法时会传递参数进来 //传递一个参数赋值给weight。 } }
-
final修饰的实例变量一般和static联合使用,成为常量。
/* final修饰的实例变量,必须手动赋值 final修饰的变量,只能赋值一次。 final修饰的实例变量一般添加static修饰 结论: static final联合修饰的变量为“常量” 常量名建议全部大写,每个单词之间用下划线(_)连接。 常量 实际上与静态变量一样,区别在于:常量的值不能改变。 常量与静态变量,都是存储在方法区中,并且都是在类加载的时候初始化。 常量一般都是公共的:public 的 原因:常量不能修改,如封装就是为了不被修改。所以常量公开也没关系,因为他改不了。 */ public class FinalText04 { public static void main(String[] args) { System.out.println(Chinese.COUNTRY); //编译报错:Error:无法为最终变量COUNTRY分配值 //Chinese.COUNTRY = "English"; //常量无法重新赋值。 } } class Chinese{ //身份证号,每个人都不一样,对象级别 String idCard; //姓名,不同对象不同姓名。 String name; //国家的值是一个固定值:“中国” //实例变量在堆中,一个对象一份,100个对象100份。 //既然这里的值不会改变,还有必要声明为实例变量吗? //实例变量既然使用final修饰,说明该实例变量值不会随着对象的变化而变化。 //final String country = "中国"; //i永远都是10,创建100个对象,i也是10. //i是10永远不会发生改变,既然这样,没必要声明为实例变量,最好声明为静态,节省内存。 //final int i = 10; //加上static以后,static与final联合使该变量变为“常量”,不再是每个对象一份。 static final int I = 10; //static final String COUNTRY = "中国"; public static final String COUNTRY = "中国"; } class MyMash{ public static final double PI = 3.1415926; }