static, super, final, this关键字

1.static

是"静态","全局"的意思,用来修饰成员变量,成员方法,或者也可以形成静态代码块。被public修饰的static变量和方法就是全局变量和全局方法

a.在类中,用static声明过的成员变量为静态成员变量,为该类的公用变量,独立于该类的任何对象。静态变量为所有对象共享,存放在数据区data segment。在类初次被加载的时候被初始化,所以,在任何对象创建之前,就可以对静态变量进行访问,无需引用任何对象。对于类的对象来说,无论你定义多少个对象,static成员变量只有一份。既可以通过对象来调用,也可以直接类名.静态变量

静态成员变量占用的内存是在一个叫做data segment的地方,一旦要new一个对象的时候,除了在堆内存里面分配一个对象所占的内存之外,还要在数据区(data segment)分配一份内存,存储静态成员变量。之后无论new多少次,还会在这个堆内存继续为对象分配内存。但是不会再在数据区分配内存了。为什么会是这样呢?因为程序初始化的过程就是先初始化静态代码,分配好内存了就不再轻易改动了。“注意:字符串常量也是在“数据区”分配内存空间”,然后还是像指针一样被指向。

其实即使没有new对象,在数据区也有为其分配内存,只是如果你不new对象的话,那么要调用它们必须使用类名。

b.用static声明的方法为静态方法,在调用该方法时,不会将对象的引用传递给它,直接使用类名.静态方法名,所以在static方法中不可访问非static的成员。因为静态方法不再是针对某个对象调用,而非静态变量又是和具体的对象绑定来使用的,所以静态方法不能访问非静态成员。

于是不难想像,静态方法中不能有this和super关键字出现,也不能访问该类的实例变量和实例方法,除非你有静态代码块,然后在里面创建了类的实例。因为你加载的时候就加载这个方法了,但是关于该类及其父类的成员变量,方法,还没有被初始化。

c.静态代码块

使用static修饰的代码块叫做静态代码块,静态代码块在JVM加载类的时候就先被执行了,无论它们被放在什么位置,它们都是先被执行,然后才是正常的代码块被执行。可以有多个静态代码块,它们会依次被JVM按照出现顺序执行,每个代码块只会被执行一次。
这个的用处很大,注意合理地利用它。特别是用于初始化。

2.super


以前我没有很好的理解super关键字的用法,现在好像清楚了,至少清楚其中一种了。也就是用于显式地调用父类里面的构造函数。

super(//括号里面是构造函数的实际参数);

这样就可以引用父类的特定的构造方法。系统就不会按照默认地去寻找父类的无参构造方法了。其实默认地相当于就执行了super();意思就是调用父类的不带参数的构造方法。

注意:super必须用在子类构造方法的第一行

关于继承的几点总结:

1)父类有的,子类都有
2)父类没有的,子类可以增加
3)父类有的,子类可以改变
4)构造方法不能被继承,只能通过super关键字调用
5)方法和属性可以被继承
6)子类的构造方法隐式地调用父类的不带参数的构造方法
7)当父类没有不带参数的构造方法时,子类需要使用super来显式地调用父类的构造方法,super指的是对父类的引用
8)super关键字必须是子类构造方法的第一行语句


3.final 关键字---“这是无法改变的”

1)final关键字可以修饰属性,方法,类,不想做任何改变可能处于两种理由:设计或者效率

2)final修饰类:当一个类被final所修饰时,表示该类是一个终态类,即不能被继承。所以说一个类不能既是final类,又是抽象类(抽象类的目的就是为了被继承)。

3)final修饰方法:当一个方法被final所修饰时,表示该方法是一个终态方法,即不能被重写(Override)。

使用final方法的原因有2个。

a.第一是把方法锁定。以防止任何继承类修改它的含义,这是处于设计的考虑,想要确保在继承类中使方法行为保持不变,并且不会被覆盖。

b.第二个原因是效率。这个问题应该留给编译器和JVM去关心,不管我们的事,因为即使你将方法改为final,也不能对效率产生明显的提升,效率问题是一个综合问题。

所以呢,除非你想要明确禁止覆盖,否则不要使用final方法。

4)final修饰属性:当一个属性(成员变量或者局部变量)被final所修饰时,表示该属性不能被改写。

有时候数据的恒定不变是很有用的,比如:

a.一个永不改变的编译时常量,对于这种情况,编译器可以将该常量值代入任何可能用得到它的计算式中。这样,就可以在编译时执行计算式,减轻了一些运行时的负担。

通常做法是和static关键字一起使用,必须用全部用大写表示,用下划线分隔各个单词。这样一个既是static又是final的域只占据一段不能改变的存储空间。

对于final类型成员变量,它必须有初值。一般来说有2种赋初值的方式

(1).在声明final类型的成员变量时就赋上初值,推荐这一种,养成良好的习惯

(2).在声明final类型的成员变量时不赋初值,但是在类的所有构造方法中都为其赋上初值。

b.一个在运行时被初始化的值,而你不希望它被改变

5)当final修饰一个原生数据类型时,表示该原生数据类型的值不能发生变化,比如不能从1变为2; 如果final修饰一个引用类型时,表示该引用类型不能再指向其他对象了,但是该引用所指向的对象内容是可以发生变化的。

6)关于final的忠告:

在设计类时,你有时候可能会想,没人会想要覆盖你的方法,有时是对的,但是不推荐。

4.this

a.this关键字通常出现在类的方法定义中,代表使用该方法的当前对象的引用。相当于可以把它看成一个变量,变量的值是当前对象的引用。

有时候使用this可以处理方法中成员变量和参数重名的情况。比如this.i=i;

从内存分析上来说,this可以看作是heap里面的一个对象内存里面的一个成员变量内存,这个变量的内容指向这个对象自己。

b.通过使用this关键字带上参数,可以在一个构造函数中调用另外一个构造函数。这是this除了单纯表示"当前对象"(注意是针对对象而不是类的概念)之外的第二个作用。

但是注意3点:

第一点,必须放在第一行。

第二点,只能调用一个其它的构造函数。(也许可以这样理解,正是因为有了第一点,如果可以调用多个的话,那么就无法放在"第一行",所以只能允许一次调用)

第三点,只能是构造函数调用构造函数,普通函数无法调用构造函数。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值