《疯狂java-突破程序员基本功的16课》读书笔记之实例变量与类变量

1.变量类型

成员变量:类体内定义的变量

局部变量:方法体内定义的变量

成员变量又可分为

实例变量(非静态变量):没有使用static修饰的成员变量

类变量(静态变量):使用static修饰的成员变量


2.实例变量和类变量

非法向前引用:

(1)public class ErrorDef{

int num1=num2+2

        int num2=20

     }

(2)public class ErrorDef{

static int num1=num2+2

        static int num2=20

     }


合法向前引用:

     public class ErrorDef{

int num1=num2+2

        static int num2=20

     }

这是因为num2是一个类变量,而num1是一个实例变量,类变量初始化在实例变量初始化之前。


实例变量属于对象,而类变量属于类的特性。在同一个JVM中,每个类只有一个Class对象,而每个类可以创建多个java对象。因此,类变量只需分配一块内存空间(堆内存),而实例变量则每创建一个实例就需分配一块内存空间(堆内存)。

通俗的说,你每new一个对象,那么这个对象就拥有自己的实例变量,如:有一个Person类,其中有age,name属性(实例变量),还有一个count变量(类变量),则你每new一个Person对象,那么这个对象就有自己的name和age,而count是所有对象所共享的变量。如果你在每次new一个Person对象时,都让count++,则就实现了计数创建对象个数的功能。


3.实例变量的初始化

(1)定义时指定初始值

(2)非静态初始化块中指定初始值

(3)构造器中指定初始值

其实java程序编译时仍然是将前两种赋值语句合并到构造器中,并且位于构造器的所有语句之前。


4.类变量的初始化

(1)定义时指定初始值

(2)静态初始化块中指定初始值

这两种方式的执行顺序与它们在类中的排列顺序相同

public class Price {
	final static Price INSTANCE = new Price(2.8);//1处
	static double initPrice = 20;//2处
	double currentPrice;
	public Price(double discount) {
		currentPrice = initPrice - discount;
	}
}
public class PriceTest {

	public static void main(String[] args) {
		System.out.println(Price.INSTANCE.currentPrice);//3处
		Price price = new Price(2.8);//4处
		System.out.println(price.currentPrice);
	}

}

这时会输出-2.8,17.2 原因:第一次用到Price类时,程序开始对Price类进行初始化,分为两个阶段

(1)系统为Price的两个类变量分配内存空间

(2)按初始化代码的排列顺序对类变量进行初始化

3处:程序第一阶段,系统先为INSTANCE 和initPrice分配内存空间,此时他们默认值为null和0.0,接着第二阶段,程序依次对他们进行赋值。先对INSTANCE 赋值要调用构造方法Price(2.8),创建Price实例,由于initPrice此时为0.0,则会得到currentPrice=-2.8。接着对initPrice赋值为20,但是已经晚了。

4处:这里必然会输出17.2

若将1处和2处调换,会发现输出为17.2,17.2,按照上面的思路,道理就非常简单了。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值