最近在搞一个springBoot多线程的问题,其中有个map的值总是会出现数据脏读的问题,原因就是因为对java中值传递和引用传递理解不够深刻,今天专门又查了查温习一遍

 

java中的数据类型

 

java 存储类型数据类型区别 java值类型内存存储位置_赋值

 

java中把内存分为了四部分

1.存代码:  编译后的class文件

2.存静态变量:   例如用static关键字的变量,例如字符串常量

3.栈(stack):  是用来装变量和引用类型的!但区别在于,装了变量以后,变量上是有值的,而引用类型本身在栈上是没有值的。

4.堆(heap):   堆可以回一句话概括,装new出来的东西!

 

综上所述,基本数据类型都存在栈中,而引用类型,变量是放在栈中,真正有内容的东西放在堆中,也就是当new了一个新的引用类型,他的内容就会放在堆中,同时栈中的引用类型变量会指向堆中你new出来的东西!

 

 

 

public static void main(String[] args) {
    int a = 25;
    float w = 77.5f;
    valueCrossTest(a, w);
    System.out.println("方法执行后的age:" + a);
    System.out.println("方法执行后的weight:" + w);

    Person p = new Person();
    p.setName("我是马化腾");
    p.setAge(45);
    PersonCrossTest(p);
    System.out.println("方法执行后的name:" + p.getName());
}
public static void valueCrossTest(int age, float weight) {
    System.out.println("传入的age:" + age);
    System.out.println("传入的weight:" + weight);
    age = 33;
    weight = 89.5f;
    System.out.println("方法内重新赋值后的age:" + age);
    System.out.println("方法内重新赋值后的weight:" + weight);
}

 

public static void PersonCrossTest(Person person) {
    System.out.println("传入的person的name:" + person.getName());
    person=new Person();//加多此行代码
    person.setName("我是张小龙");
    System.out.println("方法内重新赋值后的name:" + person.getName());
}

 

执行结果为:

传入的age:25
传入的weight:77.5
方法内重新赋值后的age:33
方法内重新赋值后的weight:89.5
方法执行后的age:25
方法执行后的weight:77.5
传入的person的name:我是马化腾
方法内重新赋值后的name:我是张小龙
方法执行后的name:我是马化腾

基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的,输出的结果证明了这一点,所以不管在方法中怎么修改age的值,后面的打印依然还是25

 

在Java中对象作为参数传递时,是把对象在内存中的地址拷贝了一份传给了参数。此时对该对象的操作会改变之前对象的值,但是因为中间有一步操作是

person=new Person();//加多此行代码 就代表person的引用指向了一个新的new person(),所以此时内部和外部的不是一个引用了,所以内部做操作不会影响外部的结果