关键字final与关键字static

一、final关键字和static的基本用法

 final:

  1)修饰类:当用final修饰一个类时,表明这个类不能被继承,同时,final类中所有成员方法都会被隐式的指定为final方法。

  2)修饰方法:将方法锁定,以防止任何继承类修改它的含义。

  备注:父类中,用final声明的方法是不能被子类覆盖的,但是同时用private修饰符的话,就可以,因为父类中的方法用private修饰时,对子类是不可见的,也就是说子类没有继承父类private修饰的方法,自然子类可以自己声明相应的方法。(但这就不是严格意义上父子类函数覆盖了)

  3)修饰变量:对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后不能再让其指向另一个对象。(换句话说:final修饰的变量内容是不能修改的,如果final修饰一个对象的引用,那么指的是这个对象的地址值是无法改变的,也就是不能再指向另一个对象,但是对象的内容还是可以修改的)

注意:

  1)父类的private成员方法是不能被子类方法覆盖的,所以说private类型的方法默认是final类型的。【子类继承父类,自然就拥有了父类的所有属性和方法的,只不过父类的private属性和方法,子类是无法直接访问到的,即只是拥有,但无法使用。】

  2)final类的方法能否被同一个包的类访问取决于访问控制符,与final无关。

  3)使用final关键字定义变量,不一定说一定要在变量定义的同时给定变量的具体数值,也可以在构造方法中完成初始化。

  4)在使用final关键字定义的方法里不一定要使用final关键字定义里面的变量。

  

  static:

  1)修饰成员变量:声明为static的变量实际上就是全局变量,只是java中没有全局变量的说法而已。当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例变量共用同一个static变量(接下来的static方法相似),就是说在类装载的时候,值分配一块存储空间,所有此类的对象都可以操纵此块存储空间。

  2)修饰方法:用static修饰的方法称为静态方法,此方法有一个好处就是,无需本类的对象即可调用此方法,可以通过‘类名.方法名’进行访问调用。 

  3)修饰类:只能用于修饰内部类。

注意:

  1)被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。

  2)static 变量前可以有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用,但是不能在其他类中通过类名来直接引用。可以这样理解:private是访问权限限定,static表示不要实例化就可以使用。

二、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));
  }
}#输出的第一个比较结果为true,第二个为false。

解释:当final变量是基本数据类型以及String类型时,如果在编译期间能知道它的确切值,则编译器会把它当做编译期常量使用,也就是说在用到该final变量的地方,相当于访问这个常量,不需要在运行时确定。这种跟C语言中的宏替换有点像。因此在上面一段代码中,变量b被final修饰,因此会被当做编译期常量,所以在使用到b的地方会直接将变量b替换成它的值。而对于变量d的访问却需要在运行时通过链接来进行,两者在获取值的阶段不同(一个是编译期,一个是运行期),导致程序运行过程中的不一样。

三、final和static的用法区别:

  1)final作用于变量是用来保证变量不可变,而static作用于成员变量用来表示只保存一份副本。

  2)final不能用于修饰构造方法;static可以修饰构造函数,构造函数不具有多态性,实际上本身就是static方法,只不是该static声明是隐式的而已。(在一个类中只有一个,而且不能带有参数;不管这个类被实例化多少次,静态构造函数在制定的程序域中只会被执行一次)

  3)final类不能被继承,没有子类,final类中的方法默认是final修饰的。static不能修饰外部类【static一般是用于修饰成员变量或者函数,但有一种特殊的用法:修饰内部类】,就谈不上什么继承不继承了。

  4)a、final方法可以被继承,也可以被重载,但不能被子类的方法重写:原因:重载是指一个类中可以有同样的修饰符,返回值,方法名,但参数个数或顺序不同的方法(不涉及到继不继承的问题,相当于多创建一个final方法而已)。而重写指的是子类继承父类后,重写父类的方法。重写是子类对父类的允许访问的方法的实现过程进行重新编写,返回值和形参都不能改变。即外壳不变,核心重写!而父类中用final修饰的方法,顾名思义,目的就是不想让其他对其更改,所以就不用说啦,只能被继承,不能被重写。

    b、static方法也不能被子类重写方法,可以被重载:原因:重写方法的目的是为了多态,或者说重写是实现多态的前提。语法上子类允许出现和父类只有方法体不一样,其他都一样的static方法,但是在父类引用指向子类对象时,通过父类引用调用的依然是父类的static方法,而不是子类的static方法【这个可以去了解一下关于继承中被static修饰的方法调用顺序】,这样就达不到我们所要的效果了。换句话说就是:语法上static支持重写,但是运行效果上达不到多态目的。既然都不是为实现这个目的的,自然就不算是可以被重写了。static可以被重载,相当于重新创建了一个静态方法而已。

  5)final修饰的属性表明是一个常数(创建后不能被修改),而static修饰的属性强调它们只有一个,java中没有全局变量的概念,static变量不能修饰局部变量,在第一次使用的时候初始化,但只会有一份成员对象(也就是还可以改变)。【static final修饰的属性表示一旦给值,就不可修改】

  6)static final和final static没什么区别,一般static写在前面。

 

 

    

 

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/yangrongkuan/p/11988883.html