浅谈Java的数据特点

1、数据类型有哪些种类?它们有什么区别?
2、变量赋值的过程发生了什么?
3、对象何时被创建?

数据类型

数据类型分为两种:基本类型和引用类型,其中String、Integer等就是我们常用的引用类型。
在这里插入图片描述

浅谈栈和堆

  • 因为栈和堆并不是本篇博客的重点,在这里只稍微提及一下今天需要用到的知识点。当我们在Java中如下图声明a和b两个变量时,栈中会生成两个引用。由于a是基本类型int的变量,所以声明a时不创建对象,a仅仅指向栈中8这个值;b是包装类String(引用类型)的变量,所以声明b时,b指向的是栈中的一个地址,通过这个地址电脑才能够找到我们创建的“ok”字符串对象。
  • 当我们对两个变量进行赋值操作时,一个对象只把栈中的值赋给另一个对象。所以说当我们对两个引用类型的变量之间进行赋值操作时,系统并不会在堆中自动新建一个对象,而是让它们的地址都指向同一个对象。
    在这里插入图片描述

对比一下这几种修改参数的方法

  • 首先我们需要创建一个Student类
public class Student {
    
    
	public String name;
	public int age;
	
	public Student(){
    
    }
	
	public Student(String name,int age){
    
    
		this.name=name;
		this.age=age;
	}
}
  • 然后创建一个ChangeDemo类,下面我们尝试用三种方法去修改Student cxd中的age,看看会有什么结果
public class ChangeDemo {
    
    
	public void change_1(int age){
    
    
		age=age+1;
	}
	public void change_2(Student stu){
    
    
		stu.age=stu.age+1;
	}
	public void change_3(Student stu){
    
    
		stu=new Student(stu.name,stu.age+1);
	}
	public void test(){
    
    
		//创建学生的初始对象
		Student cxd=new Student("cxd",20);
		
		//下面这三行代码分别单独测试,测试某一条时记得把其他两条注释掉!
		change_1(cxd.age);
		change_2(cxd);
		change_3(cxd);
		
		System.out.println(cxd.name+"的年龄是"+cxd.age);
	}
	
	public static void main(String[]args){
    
    
		ChangeDemo cd=new ChangeDemo();
		cd.test();
	}
}
  • 观察三个方法的不同之处,对比它们的运行结果,仔细思考它们运行时分别都发生了什么?
    在这里插入图片描述
    语句解读:
  • 我们传入方法change_1的参数是cxd.age,在调用这个方法的时候系统已经自动执行了一条int age=cxd.age;的语句。这个时候相当于我们已经在栈中声明了一个int类型的变量age,这个age的值等于cxd.age。此时age和cxd.age是互相独立的,修改age并不会影响cxd.age。
    -
  • 我们传入change_2的参数是cxd,这是一个Student类的变量,属于引用变量类型。在调用这个方法的时候系统同样已经自动执行了一条Student stu=cxd;的语句,这一条语句同样在栈中声明了一个和cxd拥有相同地址的变量stu。注意,因为此时cxd和stu的地址均指向同一个对象,所以此时我们对stu进行修改时,就会修改stu地址指向的那个对象的值。最后我们输出cxd.age,当然就是输出已经被修改之后的值了。
    在这里插入图片描述
  • 方法change_3和方法change_2传入的参数是一样的,所以第一个步骤都是相同的。语句stu=new Student(stu.name,stu.age+1);创建了一个新的Student对象,stu被更新为指向这个新对象的地址。此时对新的Student对象进行改变,原来的Student对象仍然不受影响。
    在这里插入图片描述
  • 小总结:当我们使用普通方法进行传参时,我们传递的只是栈中的内容。

String对象何时被创建?

  • 我们在任意一个类的主函数下试着运行下面这段代码,观察结果,比较不同,同样的,思考这些过程究竟发生了什么?
public static void main(String[]args){
    
    
		String a="ab";
		String b="ab";
		String c="abc";
		String d="ab"+"c";
		String e=new String("abc");
		String f=a+"c";
		String g=a+"c";
		
		System.out.println(a==b);
		System.out.println(c==d);
		System.out.println(c==e);
		System.out.println(c==f);
		System.out.println(f==g);
	}
  • 输出如下图所示:
    在这里插入图片描述

  • 在这里先解释一个小概念:我们去比较两个String类是否相等时用到的有符号“==”和方法“.equals()”,前者判断的是两个变量在栈中的地址是不是相同的(也就是比较它们两个是不是指向同一个对象),后者判断的是两个字符串代表的值是否相同。(也就是说两个字符串可能内容相同,但是是两个不同的对象)

  • 在刚刚这一串代码中,我们的String c,d,e,f,g表示的都是“abc”,但是在用“==”判断它们是否相等时,却出现了不一样的答案,下面博主来逐一解释。

  • a==b首先我们要明白String a="ab";这一条语句执行了什么内容?这条语句的意思是,在声明变量a的时候,先在堆中寻找是否已经有一个现成的“ab”对象,如果没有的话才创建一个“ab”对象;如果有的话,就让a指向已经存在的这个对象。所以说,当我们创建了一个String a="ab"后,再创建String b=“ab"时,变量b就会指向由a创建的这个"ab”。此时我们去判断“a==b”,也就是a和b的地址是否相同,答案当然就是true了。

  • c==d前面一个例子我们讲到,String a==“xxx”是一种特殊的创建对象的方式,这里的c和d使用的都是这种创建对象的方法,所以它们指向的也是同一个对象。

  • c==e当我们使用new方法去创建对象时,一定会在堆中开辟一个新的对象。所以指向new方法创建的对象的变量当然也就不会和任何一个变量相等。

  • c= =f;f= =g这两句的输出也是false,说明f和g也是创建了新的对象。

猜你喜欢

转载自blog.csdn.net/weixin_44710412/article/details/113578303