java申明定义对象_声明对象和创建对象的区别
1.声明对象和创建对象的区别
Java把内存划分成两种:⼀种是栈内存,⼀种是堆内存。
在函数中定义的⼀些基本类型的变量和对象的引⽤变量都在函数的栈内存中分配。
当在⼀段代码块定义⼀个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作⽤域后,Java会⾃动释放掉为该变量所分配的内存空间,该内存空间可以⽴即被另作他⽤。
堆内存⽤来存放由new创建的对象和数组。
在堆中分配的内存,由Java虚拟机的⾃动垃圾回收器来管理。java接口可以创建对象吗
在堆中产⽣了⼀个数组或对象后,还可以在栈中定义⼀个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的⾸地址,栈中的这个变量就成了数组或对象的引⽤变量。
引⽤变量就相当于是为数组或对象起的⼀个名称,以后就可以在程序中使⽤栈中的引⽤变量来访问堆中的数组或对象。
详细说明:
堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存⼤⼩,⽣存期也不必事先告诉编译器,因为它是在运⾏时动态分配内存的,Java 的垃圾收集器会⾃动收⾛这些不再使⽤的数据。但缺点是,由于要在运⾏时动态分配内存,存取速度较慢。
栈的优势是,存取速度⽐堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据⼤⼩与⽣存期必须是确定的,缺乏灵活性。栈中主要存放⼀些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。
栈有⼀个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:
int a = 3;
int b = 3;
编译器先处理int a = 3;⾸先它会在栈中创建⼀个变量为a的引⽤,然后查栈中是否有3这个值,如果没到,就将3存放进来,然后将a 指向3。接着处理int b = 3;在创建完b的引⽤变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有
了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。要注意这种数据的共享与两个对象的引⽤同时指向⼀个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。⽽⼀个对象引⽤变量修改了这个对象的内部状态,会影响到另⼀个对象引⽤变量。
2、String是⼀个特殊的包装类数据。
可以⽤:
String str = new String("abc");
String str = "abc";
两种的形式来创建,第⼀种是⽤new()来新建对象的,它会在存放于堆中。每调⽤⼀次就会创建⼀个新的对象。
⽽第⼆种是先在栈中创建⼀个对String类的对象引⽤变量str,然后查栈中有没有存放"abc",如果没有,则将"abc"存放进栈,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。
⽐较类⾥⾯的数值是否相等时,⽤equals()⽅法;当测试两个包装类的引⽤是否指向同⼀个对象时,⽤==,下⾯⽤例⼦说明上⾯的理论。
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true
可以看出str1和str2是指向同⼀个对象的。
String str1 =new String ("abc");
String str2 =new String ("abc");
System.out.println(str1==str2); // false
⽤new的⽅式是⽣成不同的对象。每⼀次⽣成⼀个。
因此⽤第1种⽅式创建多个”abc”字符串,在内存中其实只存在⼀个对象⽽已. 这种写法有利与节省内存空间. 同时它可以在⼀定程度上提⾼程序的运⾏速度,因为JVM会⾃动根据栈中数据的实际情况来决定是否有必要创建新对象。⽽对于String str = new String("abc");的代码,则⼀概在堆中创建新对象,⽽不管其字符串值是否相等,是否有必要创建新对象,从⽽加重了程序的负担。
另⼀⽅⾯, 要注意: 我们在使⽤诸如String str = "abc";的格式定义类时,总是想当然地认为,创建了String类的对象str。担⼼陷阱!对象可能并没有被创建!⽽可能只是指向⼀个先前已经创建的对象。只有通过new()⽅法才能保证每次都创建⼀个新的对象。由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使⽤StringBuffer类,以提⾼程序效率。
3、Node newNode=null;与Node newNode = new Node();
前者,是声明了⼀个对象(的引⽤),jvm并没有开辟内存放⼊⼀个对象;
⽽后者,在声明了⼀个对象的引⽤后,⼜把新开辟的没有存储任何有效值的对象的地址赋给了他。
如果类在创建后,要⾃⼰读写数据,那就必须初始化;如果是为了从其他地⽅接收引⽤,也可以省了new。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论