第九天(上) final和static关键字
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第九天(上) final和static关键字相关的知识,希望对你有一定的参考价值。
继承的出现提高了代码的复用性,方便开发,是多态的前提,但随之而来的也有问题,有些累在描述后不想被继承,或者里面的方法功能时固定的,不想让子类重写,可子类继承之后又可以重写该怎么办呢
这个时候就需要一个关键字final 意为 最终的 不可变的
Final是一个比较强的修饰符,可以用来修饰类,类的成员,以及方法
Final修饰类
在类的前面加上final
Final类不可以被继承,但可以继承其他类,是个太监.其成员方法也默认为final的,但成员变量是可以改变的
在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类。
Final修饰方法
l 子类可以继承final修饰的方法,但不能重写.
l 父类中没有被final修饰的方法,子类继承后可以用final修饰
l 如果父类中final修饰的方法同时访问控制权限为private,将会导致子类中不能直接继承到此方法,因此,此时可以在子类中定义相同的方法名和参数,此时不再产生重写与final的矛盾,而是在子类中重新定义了新的方法。
注:类的private方法会隐式地被指定为final方法。
Final修饰局部变量:
修饰基本数据类型
Final修饰的变量称为常量,只能赋值一次,就不会被改变即使赋的新值与旧值一样也不可以。
修饰引用数据类型
引用数据类型的值是地址值,被final修饰后不可以改变地址值,但地址值所指的内容是可以改变的.
Final修饰成员变量
修饰成员变量时,成员变量需要在创建对象前复制
1直接赋值 通过等号
2构造方法中赋值 没有显式的赋值那么多个构造方法都要为其赋值
Final修饰成员变量时,固定的不是内存中的值,而是手动的赋值(成员变量是有默认值的)
Final修饰方法参数
有点懵比,查了好多没有找到一个令人信服的,说法也不一样
关于final的一些题
public class Test {
public static void main(String[] args) {
String a = "hello2";
final String b = "hello";
String d = "hello";
String c = b + 2;
String e = d + 2;
System.out.println((a == c));
System.out.println((a == e));
System.out.println(a.equals(e));
}
}
结果true
false
True
为什么呢?
b被声明成了final的了,所以就是常量,常量表达式String c = b + 2;,JVM会优化成String c = "hello" + 2;,这个结果是变成编译期就是已知了,指向常量池中的hello2字符串,也就是a。
public class Test {
public static void main(String[] args) {
String a = "hello2";
final String b = getHello();
String c = b + 2;
System.out.println((a == c));
}
public static String getHello() {
return "hello";
}
}
结果:
false
这里的b虽然是常量,但是在编译期是不能获得值的,只有在运行的时候才会调用函数,初始化赋值,所以这时的String c = b+2是运行期间计算出来的,而加号连接运算符,内部则是调用的StringBuilder,然后toString,所以c相当于是new出来的String,即c是指向堆内存的地址,c内部的char数组才指向常量池中的字符串,所以明显a != c.
希望看了深入理解jvm虚拟机后可以更好的理解这些问题.
Static
定义类的时候,类中会有相应的方法和属性,而方法和属性都是通过创建本类对象调用的,当调用对象的某个方法时,这个方法又没有访问特定的数据,创建这个对戏那个就有点多余,或者说没有对象都有一模一样的常量,每new一个就出现一次这个常量,又没有办法一劳永逸呢
要解决上面的问题就要用到关键字static.
代表全局,静态的意思,用来修饰成员变量,成员方法,以及代码块.其次还有静态内部类以后有机会了解.
Static的作用: 简单来说就是方便在没有创建对象的情况下来调用方法或者变量.
Java中并不存在全局变量的概念,但我们可以用static来实现一个伪全局变量的概念,
Static修饰变量:被static修饰(只能修饰成员变量)变量称为静态变量,没有使用static修饰的叫实例变量.伴随着类的加载完成初始化.分配一次内存.每一个对象对静态变量的操作都会反应到其他对象上。
什么时候该使用static修饰呢?
当这个成员会被类的所有对象所共享,一般我们把共性的数据定义为静态变量
有什么好处呢
对象之间共享数据,访问方便,节约内存
怎么调用呢
类名.静态成员变量名
对象名.静态成员变量名 ------不建议使用该方式,会出现警告
Static修饰方法:被static修饰的方法称为静态方法.
他在类加载的时候就存在了,它不依赖于任何实例,所以static方法必须实现,也就是说他不能是抽象方法abstract。
什么时候该使用static修饰
成员方法跟着变量走,静态方法只能访问静态变量,如果成员方法中引用了静态的其他成员,那么这个方法就要声明为静态的方法.
怎么调用
类名.静态成员方法名(参数)
对象名.静态成员方法名(参数) ------不建议使用该方式,会出现警告
注意事项:
静态方法不能操作非静态变量,也不能调用非静态方法。(这个可以这样理解:静态方法属于类,直接通过类名就可以调用,而此时可能没有任何实例,更谈不上操作实例变量和调用实例方法了。)
同理,静态也不能使用this和super关键字.
所以main方法中不能直接调用非静态的方法.
为什么mian方法时静态的
为了使在调用mian方法前不创建任何实例对象.
Static静态代码块
被static修饰的代码块,我们称之为静态代码块,静态代码块会随着类的加载一块执行,而且他可以随意放,可以存在于该了的任何地方。
用来初始化静态变量。
在类加载时,在执行main方法之前执行相关操作。
没有main方法的程序可以执行吗?
Jdk1.7之前可以
之后会报错
静态导包
感觉没什么用jdk1.5之后
其目的是为了减少字符输入量,提高代码的可阅读性,以便更好地理解程序。
采用static导入包后,在不与当前类的方法名冲突的情况下,无需使用“类名.方法名”的方法去调用类方法了,直接可以采用"方法名"去调用类方法,就好像是该类自己的方法一样使用即可。
建议对于静态导入,一定要遵循两个规则:
1.不要使用*(星号)通配符,除非是导入静态常量(只包含常量的类或接口)。
2. 方法名是具有明确、清晰表象意义的工具类。
静态内部类
内部类了解
以上是关于第九天(上) final和static关键字的主要内容,如果未能解决你的问题,请参考以下文章