Java数据类型之引用型数据类型
我们接着来说数据类型,上一次我们提到了java中的八种数据类型,没有涉及到引用类型,而java的引用类型只有三种,分别是类(class)、接口(interface)、数组。
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。堆内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名。
引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!
下面我们来说说怎么区别它们俩个
- import java.util.Scanner;
-
- public class Test1 {
- public static void main(String[] args) {
- Scanner sc =new Scanner(System.in);
- int a =0;
- sc.nextLine();
- }
- }
在上面的代码中,我们定义了两个变量,其中一个为int 类型的变量a,另一个变量sc是Scanner类创建出来的一个对象,我们声明一个数据类型的时候,变量数据类型 变量名 = 变量值; 就得到了一个变量a,而变量sc 需要用到 new 操作符。他的声明方式是这样的 类名 变量名 = new 构造方法(参数列表); 我们发现引用类型的声明和基本数据类型的声明方式完全不一样。不仅仅如此,变量a是没有任何方法的,而变量sc有很多方法。看下图
我们可以看到变量sc可以调很多方法,而变量a没有任何方法。这也是区分它们的一种方式。给大家再看一段代码
- public class Test1 {
- public static void main(String[] args) {
- Student s = new Student(1,"小明","10086");
- int a = 10;
- System.out.println("学生的信息如下: "+s.toString());
- System.out.println("变量a的值="+a);
- f(s,a);
- System.out.println("调用方法后");
- System.out.println("学生的信息如下: "+s.toString());
- System.out.println("变量a的值="+a);
- }
-
- static void f(Student s, int a) {
- a=a-10;
- s.setId(1);
- s.setName("大明");
- s.setPhoneNumber("10087");
-
- }
- }
打印的结果基本数据类型作为方法参数传进去,在方法里面无法改变它的值,它只是传了一个参数副本过去。而引用数据类型作为函数参数的时候。在方法里面修改了这个数据的属性值的时候,相应的也会跟着在改变,因为引用数据类型传的是自身的地址,如果你修改了它里面的属性值,它对应的属性值也会跟着改变。
本篇要讲的就那么多了,希望对你有帮助,感谢你的阅读。