java中的final

【java中为什么会有final变量】:

    final这个关键字的含义是“无法改变的/最终的”;

    那么为什么要阻止改变呢?

    java语言的发明者可能由于两个目的而阻止改变:

    1).效率问题:

        jdk中的某些类的某些方法,是不允许被用户覆盖的,设计者可能认为,所用方法已经是最好的方法,

        用户私自覆盖,或是由于疏忽而覆盖,就会影响JVM或是系统的性能;

    2). 设计所需:

        众所周知,有些情况必须使用final关键字,比如方法中的匿名内部类的参数传递;

 

【final关键字的使用方法】:

    【修饰变量】:

        final成员变量表示常量,只能被赋值一次,赋值后值不再改变。对于基本数据类型,很好理解。对于引用数据类型,

引用变量存储的是指向实际对象的 地址,因此,其值不能修改并不意味着其所指向的对象的内容不能修改。

     就是说,这个final变量永远存放一个不变的地址,是一个常量指针,而不是指向常量的指针。

public class TestFinalArray {
	public static void main(String[] args) {
		final int[] arr = {1,2,3};
		for(int i=0;i<arr.length;++i){
			System.out.println(arr[i]);
			arr[i] += 10;
		}
		//对象内容可改变
		for(int i:arr){
			System.out.println(i);
		}
	}
}

class A {
	public int i = 0;
}
public class Test {
    public static void main(String[] args)  {
        final A a = new A();
        System.out.println(++a.i);
    }
}


        初始化:

    通常情况下,final变量有3个地方可以赋值:直接赋值,构造函数中,或是static代码块中/构造代码块中。

            由于在java的语法中,声明和初始化是联系在一起的,也就是说:如果你不显示的初始化一个值,

    系统会自动用一个默认值来对其进行初始化。(如int就是0)

            但对于final变量,在声明时,如果你没有赋值,系统默认这是一个空白域,在构造函数进行初始化,

            如果是静态的,则可以在static代码块中

    【修饰方法】:

final方法不能被子类方法覆盖,但可以被继承,可以重载

“使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。“因此,如果只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为final的。

      注意:因为重写的前提是子类可以从父类中继承此方法,如果父类中final修饰的方法同时访问控制权限为private,会隐式地被指定为final方法

将会导致子类中不能直接继承到此方法,因此,此时可以在子类中定义相同的方法名和参数,此时不再产生重写与final的矛盾,而是

在子类中重新定义了新的方法。

    【修饰类】:

        final类不能被继承,没有子类,final类中所有方法都是final的。

 

【final变量和方法为何会高效】:

    final变量和方法会在编译的过程中利用内嵌机制进行inline优化

    inline优化是指:编译时,先把已经确定的内容替换进源码-->再编译成class

    例如: final double PI = 3.1415926535897  写代码时,写多遍3.1415...容易出错,阅读性也差。

    final方法,在编译的时候直接调用函数代码替换,而不是在运行时调用函数。

【final关键字的常见应用】:

    static+final+变量: 常量。经常使用。

    final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。

    final+类:helper类经常使用。

    final用于匿名内部类的参数传递:  在多线程测试时,经常使用。


===========================================================================================

【java中变量的初始化顺序】:

     变量的初始化次序优于任何方法,甚至在构造方法的前面。对于static变量也是一样,

     如果变量是原始类型,那么它得到一个标准的原始类型的初始值,

     如果是一个对象的引用,除非你创建了一个新的对象给这个引用,否则就是null。

     static变量在类初始化时(注意不是实例),就必须分配内存空间,并且在这个类的构造函数和所有其他普通变量之前调用,

     static变量单独划分一块存储空间。

 

     java类首次装入时,会对静态成员变量和方法进行一次初始化,

     先初始化父类的静态代码-->初始化子类的静态代码-->

     (如果不创建实例,则后面的不执行)初始化父类的非静态代码-->初始化父类的构造

         -->初始化子类的非静态代码-->初始化子类的构造

     类只有在创建对象的时候才会被java类装载器装入。

 


===========================================================================================

转载来源链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值