可以理解引用算是被限制了指针吗?比如:
第一:指针可以运算,引用不行,引用只能赋值?
第二:指针可以人为操作地址,引用只能由自己分配,人为不能控制,所以相对安全?
第三:他们的相似点是都有传递的作用?
------------------------------------------------------
java里以下两个有何不同?
String a="你好" //直接赋值
String b=new String("你好") //在堆中新建一个对象
先说直接赋值那个
引用变量a在栈中,因为不是new出来的,所以保存的是值的地址吗?
举个例子:
1号盒子(1号代表栈内存里的一个物理地址 也代表引用变量a)
2号盒子(2号代表常量池里的一个物理地址)
"你好”(代表值,代表2号盒子里的装的值)
当String a="你好"时,就是1号盒子里装的是2号盒子的地址?然后2号盒子里装的内容才是真正的“你好”?那就是说当虚拟机读到1号盒子里的内容,其实是指向2号盒子的地址,通过这个地址,才能找到并读取到2号盒子里的真正值“你好”?
换句话说String直接赋值和基本数据类型赋值不一样,虽然都是在栈里,但是前者保存的是地址,还算是引用,而后者是纯的直接赋值,保存的就是数值,没有引用和保存任何地址?而且我认为String终归算是个类,虽然也有直接赋值的特性,但是和基本数据类型不一样,它直接赋值的是一个地址,必须通过地址找到值!!
不知道理解的对不对?
---------------------------------------------------
最后再看String b=new String("你好") //在堆中新建一个对象
直接举例了
1号盒子(1号代表栈内存里的一个物理地址 也代表引用变量b)
2号盒子(2号代表常量池里的一个物理地址)
3号盒子(3号代表堆内存里的一个物理地址)
"你好”(代表值,代表2号盒子里的装的值,同时也复制了一份装在3号盒子里)
那流程是什么,是虚拟机读到String b时候先在栈开辟一个内存吗,问题是你还没往下继续读,你怎么知道值或者地址是多大的,开辟多大的空间?还是说此时可以不确定空间大小,只给个首地址,然后继续读下面的,当读到new时候,在堆里又开辟一个空间同样不知道大小,然后继续读,读到"你好"时候,就指定先去常量池里找 你好,如果没有新建一个你好 ,如果有就把 你好 的值 复制一份传回堆刚才开辟的那个空间里,然后再把堆的地址传回栈刚才开辟的那个空间里?是这样的过程吗?
为什么不直接在堆里new对象时候直接 赋值 你好?非要建立个常量池 然后在从里面复制一份 传回堆给对象,这不浪费内存吗,等于整个内存里还是有2个你好的值啊,如果把常量池取消,直接赋值堆里的对象一个 你好 不就才占一个地址 多节省内存啊?是为了速度才这样的吗,因为新建一个值的速度比以前常量池建过值后下次在用的时候直接复制过来的速度要慢 所以才建立的常量池??
这里理解的对不对?
你说的东西过于复杂了,有些时候没必要这样子理解,给你一种简单的理解方法:
String a="你好";
String b=new String("你好");
String c = "Hello";
String d=new String("Hello")
你用 Eclipse 写一个简单的 Test 类,在 main 方法里面测试一下以下判断就可以了: