String s = new String("xyz");创建了几个String Object? 二者之间有什么区别?
两个。第一个对象是字符串常量"xyz" 第二个对象是new String("xyz")的时候产生的
1、内存存放的地址不同:
当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。
堆内存用来存放由new创建的对象和数组。 在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。
2、垃圾处理机制不同:
Java 的堆是一个运行时数据区,类的(对象从中分配空间。 这些对象通过new、newarray、 anewarray 和multianewarray 等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小。
生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。
但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放些基本类型的变量 (,int, short, long, byte, float,double, boolean, cha; 和对象句柄。栈有一个很重要的特殊性,就是存在栈中的数据可以共享。
3、一个是引用,一个是真实存放与内存中。
java里对象传递的时候,传递的都是引用(也就是对象的地址),这比传递整个对象高效的多。而基础类型,int,double等传递的才是值。
比如,(new ArrayList<String>).add(new String("hello")),jvm只是把new String("hello")的地址存入到了列表list里面。String str = new String("Test"),是开辟内存放入了对象,并把它的引用赋给str。
同理,BookInfo bookinfo=null与BookInfo bookinfo=new BookInfo():前者,是声明了一个对象(的引用),jvm并没有开辟内存放入一个对象;而后者,在声明了一个对象的引用后,又把新开辟的没有存储任何有效值的对象的地址赋给了他。
bookinfo=test.getinfo(),又把它指向了另一个地址。
new String对象的时候,又创建了一个对象保存在内存中,在运行时确定
String s = new String("xyz"); //先常量池再内存
String s1="xyz"; //常量池
System.out.println(s==s1); //false
ps:==用来判断是否引用同一对象,s和s1位于不同环境中,自然不是引用同一对象