博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
谈谈关键字new
阅读量:5051 次
发布时间:2019-06-12

本文共 3012 字,大约阅读时间需要 10 分钟。

1.在情人节那天,无意间看到空间有人说,没有对象就new一个,然后就可以........

程序中我们常用到X a=new X(), new在这里是创建一个对象,也可以叫做创建一个实例,我们先谈谈后半部分new X()做了什么,new X这个对象的时候,必然会调用这个类的构造方法,并且需要在堆中给对象分配内存,前半部分X a只是在栈中申明了一个内存空间,这个内存空间的类型是X,后半部分的值不可能直接赋值给a吧,如果new X()的值很大怎么办?所以a的值就是后半部分的内存的地址,也叫引用变量。所以我们搞懂了X a=new a()的后半部分是实例或者对象,前半部分是引用变量。

2.String中的new

我们在使用String a=“abc”类似的这种语句的时候,我们有没有想过,我们为什么不用String a=new String(),而用String a=“abc”呢?它们俩有什么区别?

public class StringTest {    public static void main(String[] args) {        String str1="abc";        String str2=new String("abc");        String str3=null;        str3=str1;                if(str1==str2){            System.out.println("str1和str2是一个内存空间的");                    }        if(str1==str3){            System.out.println("str1和str3是一个内存空间的");        }        if(str2==str3){            System.out.println("str2和str3是一个内存空间的");        }            }}

运行结果:

str1和str3是一个内存空间的

大家都知道==是判断对象是否为一个内存空间的。我们想想为什么运行结果是这样?

先看看String类型的对象的产生方法:

String有一个所谓的String constant pool ,是一个特殊的一个空间(注意这个是在PermGen上的,它是JVM用来保存类定义和常量池的保留空间,缺省是64M)保存String常量。String str = “abc”是先定义一个名为str的对String类的对象引用变量:String str;再用equals方法(String类覆盖了equals方法)判断这个特殊空间(String constant pool )是否有abc,有则将原来在栈中指向abc的引用赋值给str,否则就在这个特殊空间(String constant pool )上开辟一个存放字面值为"abc"的地址,接着在堆上创建一个新的String类的对象o,并将o 的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。最后将str指向对象o的地址。

String str2 = new String("abc"),这里"abc"本身就是pool中的一个对象,而在运行时执行new String()时,将pool中的对象复制一份放到heap中,并且把heap中的这个对象的引用交给s持有。这条语句就创建了2个String对象。它引用堆上创建的abc对象。所以str和str2是指向不同的对象,它们是不同的。那么这样话程序的运行结果就好理解了。

结论:运行结果正好验证了我们1所提到的,使用String a="abc"相比与String a=new String("abc")更好,原因就是节省空间。

3.new关键字牵扯的向下或者向上转型

A.java

public class A {    public String f(A obj)    {        return("A");    } }

B.java

public class B extends A{     public String f(B obj)        {            return("B");        }        public String f(A obj)        {            return("Aplus");        } }

Test.java

public class Test {    public static void main(String[] args) {         A a1 = new A();         A a2 = new B(); //子类对象转化为父类,称为上转型,不需要强制转换。         B b = new B();         System.out.println(a2.f(b));          //不会出现ClassCastException         B b1 = (B) a2;           System.out.println(b1.f(b));         System.out.println(b1.f(a1));        //会出现ClassCastException         B b2=(B) a1;         System.out.println(b1.f(b));         System.out.println(b1.f(a1));                  //父转子是危险的,这种情况会可能出现内存越界,所以向下转型需要用instanceof判断         if (a2 instanceof B) {                B b1 = (B) a2;  //父类对象转化为下转型,此时需要使用强制转换,此时需要先判断要转换的这个对象(也就是a2指向的这个对象)是不是B类的实例                System.out.println(b1.f(b));                System.out.println(b1.f(a1));            }        }         }

 

运行结果:

AplusBAplus

结论:

向上转型:

优点:向上转型体现了类的多态性,增强了程序的简洁性,上转型对象可以操作和使用子类继承或者重写的方法。

缺点:上转型对象丧失了对子类新增成员变量或新增的方法的操作和使用。

向下转型:

给个例子,如果你说麻雀是鸟(向上转型),对的。那如果你说鸟是麻雀(向下转型),mdzz。

4.java创建对象时, = null和new 出一个对象为空(String str=new String())的区别

前者,是声明了一个对象(的引用),jvm并没有开辟内存放入一个对象;而后者,在声明了一个对象的引用后,又把新开辟的没有存储任何有效值的对象的地址赋给了他。

 

转载于:https://www.cnblogs.com/huhu1203/p/7533478.html

你可能感兴趣的文章
黑马 StringBuffer
查看>>
dedecms /include/uploadsafe.inc.php SQL Injection Via Local Variable Overriding Vul
查看>>
ThinkPHP--浏览历史
查看>>
iptables
查看>>
mysql常用函数
查看>>
xml=>数组
查看>>
Python全栈开发
查看>>
HDU 5171 GTY's birthday gift 矩阵快速幂
查看>>
原生JS获取url汇总
查看>>
设置session生存时间问题
查看>>
CentOS 添加新的硬盘之后不停机操作
查看>>
3.1 一个简单的Java应用程序
查看>>
函数笔记
查看>>
正则表达式补充
查看>>
Vue中全局和按需引入Echarts
查看>>
框架目录
查看>>
MSSql技巧之快速得到表的记录总数
查看>>
RDIFramework.NET — 基于.NET的快速信息化系统开发框架 - 5.3 数据库连接管理模块...
查看>>
Webservice测试从头来
查看>>
no such table
查看>>