谈谈关键字new

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));
            }
        } 

}

运行结果:

Aplus
B
Aplus

结论:

向上转型:

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

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

向下转型:

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

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

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

时间: 2024-09-30 00:54:07

谈谈关键字new的相关文章

SEO关键词优化正确方法解析

搜索引擎如何判断,哪个字才是关键字?想要晓得若何精确的利用关键字,我们必要先从搜索引擎原理来相识,毕竟上搜刮引擎是无法判断一篇文章哪些字是属于关键字的,搜刮引擎重要判断方法是以数目来区别,在100个词中,a关键字出现了10次,b关键字出现了5次,那a关键字的紧急性就大于b关键字,以此类推.那大概会有人说那我网页上就写满关键字,排名结果不就最好? 在从前关键字堆砌的方法确实可行的.但是如今这招已经行不通,如今搜刮引擎会以关键字密度来判断,公道的关键字密度应该介于2%-8%之间,低于2%表现不紧急,

谈谈dynamic关键字

谈谈dynamic关键字 前言 今天和谈了两年的女朋友分手了,一开始我还觉得是因为这次的吵架,因为我今天一天没联系她,她就生气了,说了分手,我是说一开始我以为是这样.然后我想了想,矛盾就像不停的在往一个瓶子里到硫酸,有可能因为这一滴的缘故导致瓶子里的硫酸溢出来了,有了矛盾就要解决了,珍惜眼前人. 正文 废话说了一大堆,说点正经的,C#4.0提供了一个关键字dynamic,我在以前的时候说过这个关键字.今天来看看dynamic到底是什么.它是怎么工作的呢? 先来看一个简单的案例: static v

谈谈一些有趣的CSS题目(十五)-- 谈谈 CSS 关键字 initial、inherit 和 unset

原文:谈谈一些有趣的CSS题目(十五)-- 谈谈 CSS 关键字 initial.inherit 和 unset 开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉到生僻的 CSS 属性,赶紧去补习一下吧. 不断更新,不断更新,不断更新,重要的事情说三遍. 谈谈一些有趣的CSS题目(一)-- 左边竖条的实现方法 谈谈一些有趣的CSS题目(

谈谈 C# 语言中的 static 关键字

01: /// <summary> 02: /// 使用字节数组中的值初始 ZipInteger 结构的新实例 03: /// 注意:本构造函数会破坏传入的 bits 参数的值. 04: /// </summary> 05: /// <param name="bits">顺序为 big-endian 的字节值的数组</param> 06: public ZipInteger(byte[] bits) 07: { 08: if (bits

谈谈C++的volatile关键字以及常见的误解

转载请保留以下声明 作者:赵宗晟 出处:https://www.cnblogs.com/zhao-zongsheng/p/9092520.html 近期看到C++标准中对volatile关键字的定义,发现和java的volatile关键字完全不一样,C++的volatile对并发编程基本没有帮助.网上也看到很多关于volatile的误解,于是决定写这篇文章详细解释一下volatile的作用到底是什么. 编译器对代码的优化 在讲volatile关键字之前,先讲一下编译器的优化. int main(

谈谈java中的super和this关键字

知识点: 在java类中使用super引用父类的成分,用this引用当前对象 this可以修饰属性.构造器.方法 super可以修饰属性.构造器.方法 一:this关键字 this可以修饰属性.构造器.方法:用this引用当前对象 (1)this修饰属性,调用类的属性 //set方法public void setName(String name) { this.name = name;} //有参数构造函数 public Person(String name){ this.name=name;}

JAVA面试题 请谈谈你对Sychronized关键字的理解?

面试官:sychronized关键字有哪些特性? 应聘者: 可以用来修饰方法; 可以用来修饰代码块; 可以用来修饰静态方法; 可以保证线程安全; 支持锁的重入; sychronized使用不当导致死锁; 了解sychronized之前,我们先来看一下几个常见的概念:内置锁.互斥锁.对象锁和类锁. 内置锁 在Java中每一个对象都可以作为同步的锁,那么这些锁就被称为内置锁.线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁.获得内置锁的唯一途径就是进入这个锁的保护的同

谈谈java中的synchronized关键字

1.synchronized的3种用法 public class Client { public static void main(String[] args) { testSynchronized(); } private static void testSynchronized() { new Foo().sayHello(); } static class Foo { //修饰代码块 void sayHello() { synchronized (this) { System.out.pr

结合具体项目谈谈对抽象类的理解

抽象类面向对象的语言中经常使用的类,网上也有各种各样的剖析,大致上都是做了以下方面的对比:1 抽象类和普通类的区别.2 抽象类和接口的区别. 3 抽象类中的虚方法和抽象方法的区别,首先去找到这些重大的区别,然后针对具体的项目来谈谈对这些概念的理解. 1 抽象类和普通类 A.都可以被继承 . B.抽象类不能被实例化,只是用来继承的,普通类可以实例化. C.抽象方法只有含方法声明而没有方法体且必须包含在抽象类里面. D.子类继承抽象类必须实现抽象类中的抽象方法除非子类也是抽象类. E.抽象类中可以包