您的位置:首页 > 其它

变量的一些基本知识

2017-06-21 15:16 204 查看
定义类其实就是定义类的成员(成员变量和成员方法)

ps:java中方法分为构造方法和成员方法

成员变量和局部变量的区别

在类中的位置不同

成员变量 类中方法外

局部变量 方法内或者方法声明上

在内存中的位置不同

成员变量 堆内存

局部变量 栈内

生命周期不同

成员变量 随着对象的存在而存在,随着对象的消失而消失

局部变量 随着方法的调用而存在,随着方法的调用完毕而消失

初始化值不同

成员变量 有默认的初始化值

局部变量 没有默认的初始化值,必须先定义,赋值,才能使用。

静态变量和成员变量的区别

所属不同

静态变量属于类,所以也称为为类变量

成员变量属于对象,所以也称为实例变量(对象变量)

内存中位置不同

静态变量存储于方法区的静态区

成员变量存储于堆内存

内存出现时间不同

静态变量随着类的加载而加载,随着类的消失而消失

成员变量随着对象的创建而存在,随着对象的消失而消失

调用不同

静态变量可以通过类名调用,也可以通过对象调用

成员变量只能通过对象名调用

定义方法时会用到形式参数

形式参数的问题:

基本类型:形式参数的改变不影响实际参数

引用类型:形式参数的改变直接影响实际参数(String 除外,比较特殊)

在执行方法时,调用方法时的参数会传给形式参数,此时形式参数(可以看成局部变量)会先在栈中开辟一块空间进行复制调用参数的值(基本数据类型)或内存地址(引用数据类型),然后用来进行运算。这样的好处是:

1.执行完方法后,基本数据类型的调用参数不会发生值的改变。引用数据类型(String除外)

2.

先看看基本类型的参数传递:

以下面代码为例:

public class PassValue {

public staticvoid main(String[] args) {

int x=5;

change(x);

System.out.println(x);

}

Public staticvoid change(int x) {

X=3;

}

}


方法运行时参数的传递过程是,会先在方法区开辟一个其所定义的类型的变量的空间,形参变量(就是方法里的局部变量)会指向这个空间。见图 1_1。


之后把实参的值,赋给这个局部变量。这时方法内的局部变量x被赋值为 5。见图1_2 .



到此,调用方法change参数传递结束。看看后面代码运行的情况。方法内,局部变量的x被赋值3了,但方法外的x的值是5。见图1_3。


Change方法结束,change方法中x占据的内存被释放,程序返回。Main方法里的变量x 仍是 5,并没有改变。见图1_4.


到此,整个程序执行结束。

再看看基本类型的参数传递:

public class PassRef {
int  x;
public static void main(String[] args) {
PassRef obj = new PassRef();
obj.x=5;
change(obj);
System.out.println(obj.x);
}
public static void change(PassRef obj) {
obj.x=3;
}
}


上面代码运行结果是 3。

下面结合图来看看其执行过程。

首先,调用change方法前,main方法中的内存情况如图1, 我们看这时main 方法中的obj引用指向堆内存的情况,而这时change方法内的obj没有具体赋值。



而当执行change方法时,再看一下内存状态,如图2. 可以清楚看见change 方法内的局部变量obj的值与main 方法里的obj值是一致的。因为main中的obj的地址会复制一份给change的方法区中,它们都指向堆内的同一个对象。但可以清楚看到,main里的obj和change里的obj 是两个独立的变量,只是叫的名字一样,它们指向堆内同一块内存。个人觉得这块是最关键的。



接下来看看change 方法运行的情况,如图3, 可以看见,在change方法里对对象的操作,会改变对象的内容。注意:obj不变,但obj指向的对象的内容改变了。原来x=5, 现在是3了。



最后,change方法结束,change中的obj变量被释放,但堆内的对象仍被main方法中变量obj引用,其内容改变了。如图4。



最后说说String

字符串是常量,它的值在创建之后不能更改。

String str = “eva”;

字符串是引用变量,引用类型的变量通常包含一个指向实例的指针,变量通过该指针来引用实例。所以首先会现在堆中开辟一个空间,栈中地址会存放这个堆空间的内存地址作为引用实例,在存值的时候会在堆空间用来存放在常量池中“eva”的内存地址。

当str = “q”;时,JVM会现在常量池中寻找是否有“q”这个字符串,如果没有就在常量池中创建,并把“q”的堆中的引用实例。

详细找了篇文章下面放 地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: