java语言中没有“指针”的说法的,更多时候是引用赋值还是传值赋值之分,这对于一些资深的老司机来说,确实使用避不开的问题。
探索代码一:
long A=1; long B=1; System.out.println("变量A内存地址:"+System.identityHashCode(A)); System.out.println("变量B内存地址:"+System.identityHashCode(B)); B=2; System.out.println("A=>"+A+" B=>"+B); System.out.println("第二次:变量A内存地址:"+System.identityHashCode(A)); System.out.println("第二次:变量B内存地址:"+System.identityHashCode(B));
运行结果:
变量A内存地址:1878246837 变量B内存地址:1878246837 A=>1 B=>2 第二次:变量A内存地址:1878246837 第二次:变量B内存地址:929338653
结论:
在java中,jvm在执行代码的时候,自动会去找以前是否有同样值的内存空间,当有同样空间值时候就会分牌这个原来空间内存地址给新的变量,这就是引用赋值。这样做就是为了减少内存使用量。当我们使用“=”改变其中一个值时候,jvm会自动在申请一个内存空间,给这个变量,不会影响其它变量的值,这和其它编程语言的指针改变值不一样。
探索代码二:
public class cc{ public static ArrayList<T1> Array=new ArrayList<T1>(); public static void main(String[] args){ T1 t1=new T1(); System.out.println("对象T1内存地址:"+System.identityHashCode(t1)); fun1(t1); System.out.println("对象T1.a=>:"+t1.a); T1 t2=Array.get(0); System.out.println("对象T2内存地址:"+System.identityHashCode(t2)); cc cc1=new cc(); cc1.fun2(t2); System.out.println("对象T1.a=>:"+t1.a); System.out.println("对象T2.a=>:"+t2.a); } public static void fun1(T1 t1){ System.out.println("参数中,对象T1内存地址:"+System.identityHashCode(t1)); t1.a=2; Array.add(t1); } public void fun2(T1 t1){ System.out.println("参数中,对象T1内存地址:"+System.identityHashCode(t1)); t1.a=4; } } class T1{ public int a=0; }
运行结果:
对象T1内存地址:856419764 参数中,对象T1内存地址:856419764 对象T1.a=>:2 对象T2内存地址:856419764 参数中,对象T1内存地址:856419764 对象T1.a=>:4 对象T2.a=>:4
结论:
java语言中,所有的对象都是通过指针传递,无论中静态方法或者普通方法,还是Array中,一旦其中一个环节改变了值,同一个地址的对象值都会响应的改变。弄清了这点,对于一些java编程中很重要。
探索代码三:
public class cc{ public static ArrayList<T1> Array=new ArrayList<T1>(); public static void main(String[] args){ T1 t1=new T1(); Array.add(t1); ArrayList< T1Thread> poolThread=new ArrayList<>(); for (int i=0;i<100;i++) { poolThread.add(new T1Thread()); } for (T1Thread t1Thread :poolThread){ t1Thread.start(); } for (T1Thread t1Thread :poolThread){ try { t1Thread.join(); }catch (Exception e){ } } System.out.println(t1.a); } } class T1{ public int a=0; } class T1Thread extends Thread { public void run() { for (int i=0;i<100;i++){ synchronized (cc.Array.get(0)){ cc.Array.get(0).a++; } } } }
运行结果:
10000
结论:
这段代码是不会出现脏数据的,用于执行结果都一样。synchronized也是通过对象指针作为锁定依据,这点对于多线程之间相互锁对象意义重大。
最后,感谢java,感谢跟我一样技术的人。