JAVA SE面向对象编程之final
1.final修饰那些量
a.修饰类(不能与abstract同时使用;final修饰的类不能有子类)
b.修饰方法(不能与abstract同时使用;可以和static修饰类方法;访问修饰符可以为private,但是无意义;final方法不能重写)
c.实例变量(获得初始值后不能重新赋值。可以定义时就给赋值,也初始化代码块赋值,也可以构造数赋值。不能不赋值,赋值后也不能重新赋值)
d.类变量(获得初始值后不能重新赋值。可以定义时就给赋值,也初始化代码块赋值。不能不赋值,赋值后也不能重新赋值)
e.形参(不能再在方法里面赋值)
f.局部变量(程序不会给局部变量赋初始值,final修饰局部变量可以定义时就给赋值,或者定义后赋值)
g.修饰引用变量,只保证引用变量地址不变,内部值可以改变
2.final还未赋初值时不能直接访问,但可以用方法访问
public class FinalErrorTest { // 定义一个final修饰的实例变量 // 系统不会对final成员变量进行默认初始化 final int age; { // age没有初始化,所以此处代码将引起错误。 // System.out.println(age); printAge(); age = 6; System.out.println(age); } public void printAge(){ System.out.println(age); } public static void main(String[] args) { new FinalErrorTest(); } }
3.无论final修饰的是类变量,实例变量还是局部变量,若定义该变量时直接赋值,且值在编译阶段能确定下来,则这个final修饰的变量就是一个直接量(宏替换)
如果是表达式赋值,表达式中是基本的算术表达式或者字符串连接,这种final变量也将会成为一个直接量
若无final修饰
public class FinalReplaceTest { public static void main(String[] args) { String a="testa"; System.out.println(a); } }
使用javap -c查看反编译结果
final修饰,定义时赋值,且值在编译期能确定
public class FinalReplaceTest { public static void main(String[] args) { final String a="testa"; System.out.println(a); } }
使用javap -c查看反编译结果
下面也会进行宏替换
public class FinalReplaceTest { public static void main(String[] args) { final int a = 5 + 2; final double b = 1.2 / 3; final String str = "疯狂" + "Java"; final String book = "疯狂Java讲义:" + 99.0; } }
4.不可变类,指创建类的实例后,实例的实例变量不可以改变(8中包装类和java.lang.String为不可变类)
a.实例变量使用final和private修饰(final修饰,无法修改;一般实例变量使用private,进行封装)
b.提供代参构造器,来初始化实例变量(初始化实例变量的一种方法)
c.为该变量提供getter方法,不提供setter方法(没方法修改)
e.如有必要,重写hascode()和equals()方法
5.缓存实例的不可变类
题目
1.判断用字母标识的地方那些那些赋值是正确的,那些事错误的
public class FinalLocalVariableTest { public void test(final int a) { a = 5; //a } public static void main(String[] args) { final String str = "hello"; //b str = "Java";//c final double d;//d d = 5.6;//e d = 3.4;//f } }
2.引用变量赋值
class Person { private int age; public Person(){} // 有参数的构造器 public Person(int age) { this.age = age; } // 省略age的setter和getter方法 // age的setter和getter方法 public void setAge(int age) { this.age = age; } public int getAge() { return this.age; } } public class FinalReferenceTest { public static void main(String[] args) { // final修饰数组变量,iArr是一个引用变量 final int[] iArr = {5, 6, 12, 9}; System.out.println(Arrays.toString(iArr)); // 对数组元素进行排序,合法 Arrays.sort(iArr); System.out.println(Arrays.toString(iArr)); // 对数组元素赋值,合法 iArr[2] = -8; System.out.println(Arrays.toString(iArr)); // 下面语句对iArr重新赋值,非法 // iArr = null; // final修饰Person变量,p是一个引用变量 final Person p = new Person(45); // 改变Person对象的age实例变量,合法 p.setAge(23); System.out.println(p.getAge()); // 下面语句对p重新赋值,非法 // p = null; } }
3写出下面程序的运行结果
public class FinalReplaceTest { public static void main(String[] args) { String a ="疯狂JAVA"; String b="疯狂"; String c="JAVA"; String d = b+c; System.out.println(a == d); final String e="疯狂"; final String f="JAVA"; String g = e+f; System.out.println(a ==g); System.out.println(b==e); } }
4.判断下面程序是否会报错
public class FinalMethodTest { public final void test(){} } class Sub extends FinalMethodTest{ public void test(){} }
5.判断下面程序是否会报错
public class FinalMethodTest { private final void test(){} } class Sub extends FinalMethodTest{ public void test(){} }
6.写一个存在两个实例变量(分别为String firstName,String lastName ),类名称为MyName的不可变类
7.写一个存在两个实例变量(分别为Integer age,MyName myname),类名称为Person的不可变类
8.编写一个缓存部分实例的不可变类
9.详细说明final可以修饰那些量(参考总结1)
答案:
1.错误 正确 错误 正确 正确 错误
3.false true true
4.会报错
5.不会报错
posted on 2020-03-30 18:41 xingshouzhan 阅读(149) 评论(0) 编辑 收藏 举报