Java初学,这种问题贻笑大方了,还请各位大侠不吝指教。    我学的还不深,似乎Java 所有的对象定义都使用,诸如 Myclass mc=new Myclass()的语句,相当开辟了一片内存,同时返回了指向这片内存的指针(Java喜欢说是句柄,引用)。    既然所有的定义,都这么干,那作为一个语种,就把new关键字取消好了,这种事情让编译器自己知道不就可以了?为什么还要有这个关键字呢?

解决方案 »

  1.   

    如果不作为关键字检查,那么如果有人定义一个名字为new的变量,编译器该如果处理?
      

  2.   


    名字而已哎,如果编译器不用大家显示的使用new,自动的默默的分配好了内存。那么new就给大家随便拿来当变量有什么不可以呢?
      

  3.   

    不显示的使用new,你怎么知道这是在创建对象还是在调用方法?我创建一个名字叫MyClass的类,然后写一个叫MyClass的方法,请问,你怎么知道是调用的方法还是创建的类?Sun公司的人不是吃干饭的!
      

  4.   

    用spring吧。IOC控制反转。spring工厂自动帮你创建
      

  5.   


    所以说我可能基础还不够啊,呵呵。不过你说的这是什么意思?难道,你的意思是单单一句“MyClass mc;”可能存在二义性?除了表示声明,还可能表示调用构造函数?还是说,你觉得不用new,没法传递参数给构造函数了?用Myclass mc(TYPE);不就行了?
      

  6.   

    谢谢您,我还没有这么深入,设计模式我打算在完全熟悉Java语法的基础上,再多多了解:)
      

  7.   

    new如果可以省,为什么要new这个关键字。
    语法,就是一种规范,java虚拟机可以解析的规范。
    木有规范,给虚拟机造成强大的压力,硬是要虚拟机通过好多种方案中选出一种可以和你臆想的方案相匹配,这在性能上要很大的代价。你是要性能还是要写代码方便?要性能学机器语言/汇编/c。
    要方便,貌似也没用绝对的方便。不过现在的很多语言正往这方向发展.而且很多方便也有局限性,也只是某一领域上有很方便,其他方面又很不方便。
      

  8.   

    首先,MyClass mc表示的是声明一个变量,这个变量其实就是一个指针,这里面存的是一个地址。其次,不知道你有没有学到继承,当你学到继承的时候你就会明白为什么不能仅仅用这句话表示创建一个对象了
      

  9.   

    楼主naive啊
    如下代码:
    public class Test {
    public Test() {
    System.out.println("const");
    }

    public static Test Test() {
    System.out.println("normal method");
    return new Test();
    }

    public static void main(String[] args) {
    Test t = new Test();
    }
    }如果main方法中Test t = new Test();没有new,你觉得是要调用构造方法呢还是普通方法public static Test Test()?
      

  10.   

    如果Test t();这种定义方式,又带来了c++的问题,是不是又需要定义拷贝构造函数呢,还要引入指针呢?问题只会越来越复杂
      

  11.   


    你要考虑到,用户可能只是声明变量,并不想马上生成对象,需要的时候再生成对象
    如果MyClass mc马上就生成对象了,那么对于有条件创建对象来说,就会造成过多的垃圾
    比如
    MyClass mc; //如果没有关键字,这里就会生成一个无意义的对象,
          //如果是带参数的,参数又是动态的并且是个很复杂的对象无法直接用代码代替,那么该如何声明
    if (contidion1) {
        mc = new MyClass(arg1); //所以保留new,给用户一定的自由空间,才是有意义的
    } else {
        mc = new MyClass(arg2);
    }
      

  12.   

    那我们所有的 + 发运算都是用 + ,是不是我们也可以吧 + 取消让jvm自己处理呢。
    new是一个关键字,也是一个运算符,他要告诉jvm在遇到他的时候知道要去做什么事情,如果没有这个new运算符jvm怎么知道你是要创建一个对象的呢
      

  13.   

    谢谢,这个例子让我稍微明白点了。普通函数名怎么还可以与构造函数名一样啊……好像和C++还是不大一样对于您的这个例子,我觉得,如果java这样规定:
    1. Test t或者Test t()表示创建一个对象的引用(自然会调用构造函数)
    2. Test t=Test();表示调用普通函数
    不就行了?
      

  14.   

    LZ,记住一句话,入乡随俗。没必要纠结,否则大家还会讨论为什么不取消C++的delete,还有把VB.NET的IF THEN ... END IF统一成C语言风格...这样没完没了的问题把我在前两天其他帖子里面的话再概括一遍:不是说java的思维方式(或者编码方式)就是正确的,就是最好的。这就好比,中文习惯说“我认为这个不...”,而英文一般习惯说“I don't think ...”。没谁对,谁错,完全是习惯问题。建议在学习java或者其他语言(包括人类/编程语言)的时候,也按照这种入乡随俗的方式thinking in ...之所以要入乡随俗,就是因为大家都是这么思考,包括Java语法的制定者,JDK或者其他类库、框架的编写者,也包括你的同事,都是以同样一种思维方式(或许是好的或许是不好的,who cares)在工作,你只有融入他们,才能事半功倍,否则,多半是撞了南墙还一事无成。编程语言如是,人类语言亦如是。
      

  15.   

    new 就好比是生儿子 ,你不去new 怎么你晓得是不是 自己的呢 呵呵
      

  16.   

    class Test {
        ...
    }public class Main() {
        public static Test Test() { //这下没有同名构造方法了吧    }    public static void main(String[] args) {
            Test t = Test(); //这时该如何处理 --A         //而且,LZ有没有想过有条件生成对象的情况,如
            if (contidion1) {
               t = Test(arg1); //如果arg1是动态等到的或者是个很复杂的对象,那么在A处应该如何声明
             //当然,LZ可能觉得可以在这里才声明 Test t = Test(arg1); //那么C处如何知道有t这个变量
           } else {
               t = Test(arg2);
           }       t.xxx(); //--C
        }

    所以,提供new,给用户创建对象的自由,才是有意义的
      

  17.   

    谢谢,我又去复习了一下C++的概念(C++也是才学不久),那么#14 楼我的问题,应该就是你在这里要说的了。此外,我其实也理解 #15楼说的道理。如果我在这里说,拷贝构造函数也不麻烦,又或者,引用不就是指针嘛,之类的话,会被大家觉得很无聊吧?确实没必要全部都统一。我想,我问这个问题的原因,是因为以前用的一直是C,最近开始学C++和Java,陡然觉得很多东西,有利有弊,才会有些疑问。Thing in Java粗略的看了一遍,可能理解不够深入,现在正打算看第二遍。这个问题我先留着,等理解深刻了,或许问题就解决了吧:)帖子再放一放,看看有木有更有说服力的回复,稍后给分:)
      

  18.   


    我已经说过,这会有很多问题的Test t这种,在c++中,是可以创建对象的,且t不是指针类型如果假设t为引用(阉割的指针)
    那么我想要声明一个t变量,指向null该怎么办?
      

  19.   

    提供new,就是简化了所有的处理,简化了对象的访问模式——统统通过引用来访问的没有new,肯定可以做到,但会更复杂,为什么要去掉呢
      

  20.   

    还有多态,其实8楼已经说了
    Student extends Person;Person p = new Student();
    如果木有new,你的p只能定义成Person的实例,不能有上面那种写法。
    而多态是java的重要特性,灵活性很高。你这么做,就把多态给封杀了,为了一句简单的便利,付出代价是惨痛的。
      

  21.   

    有没有想过父类的引用指向子类的对象这种情况呢?想想Java最大的优点吧!!!!!!!!
      

  22.   

    回 #21 和 #22楼:我的意思是没有new的情况下,Person p定义,让编译器生成的就是个引用,而不是实例,只是编译器自动为这个p指向了一片内存区(原本这片区域我们要new显示写一下,现在编译器自己知道,我们就不写了)。
    这样做不会影响 多态性 机制吧? 至少我觉得:
    1.父类引用子类对象,这个不影响,毕竟父类引用指向的内存区域不会超过子类对象内存的范围
    2.如果说的是后期动态绑定,应该是java虚拟机记录了些信息,才能在“后期”做到,那么现在没有new,虚拟机依旧可以记录,信息量不会变少的。再次声明,仅仅讨论而已,呵呵,其实已经对各位大侠很是佩服了,讨论才有进步,对不:)
      

  23.   


    嗯,我刚才也在想,如果自动分配区域了,想让他指向NULL怎么办……好像Java就没打算定义过指向NULL的引用吧?? 之前看书的时候,好像脑子里就有这个疑问……当时的理解是,反正有个垃圾回收器,一旦回收了,且引用的作用范围早已不在的时候,也就无所谓去手动NULL了。
    也因此,更没必要一开始就NULL了。
    不知我的理解对不对
      

  24.   


    谢谢你 #17 楼,你的这个例子,正式Java的独创性给我带来的困惑,基于Java眼下已有的机制,你的代码,我就不讨论没有new该怎么说了,否则又会有向C++靠齐的嫌疑。不过,在C++中,确实也有这样的问题:如下代码可以编译通过,而注释的那一行,开放注释(去掉注释符)则编译不过了-_-|||#include <iostream>class A{};A A(A  aa)
    {
      return aa;
    }int main()
    {
        //A ee;   //此行去掉注释符,则编译不过了
        return 0;

      

  25.   

    一开始就声明为null的代码很有必要BufferedReader reader = null;
    FileInputStream fis = null;
    try {
     fis = new FileInputStream(System.in);
     reader = new BufferedReader(fis);.....
    } fianlly {
     if(reader !=null) {
     //close... 
    }
     ...
    }
    还有数据库操作,基本都是这么个try..finally模式
      

  26.   

    你有仔细看人家说的是什么吗?Person p = new Student();Person是父类,Student是子类,父类的引用指向子类的对象,对于我们调用p这个引用的人来说,我们不需要知道我们调用的方法时哪个类的,可以使Student,也可以是Teacher,但是如果照楼主那样说的话,p指的永远都是只是Person这个类。
      

  27.   


    你说的没错,其实不仅仅是数组,形参如果是非内置类型,那么方法里可能还是要进行是否null的判断。我在想,我起初问这个问题,是因为隐约觉得,Java似乎希望把“指针”相关的概念都屏蔽掉。因此我才会觉得new、null这种带有“指针”痕迹的东西都能内部封装,或许才叫完美吧。不知道Java后续的版本会怎样发展……我继续看书了,谢谢各位大侠。
      

  28.   


    哎?你这个说的是什么意思?这里,你说的p虽然定义成了Person,但实际指向Student,我明白的。p还可以调用Student里的方法,我也知道。前提当然是调用那些Person和Student都有的方法。Student后来扩展的方法肯定不能调用,对不对?然后,如果没有new这种东西,并不会削弱上述好处啊。比如:
    1. Methone Display(Person p); //这里我仍然可以传入一个Student s定义的s啊,这个时候我们在Display内部,不用管p到底指代的是个Student还是个Teacher——你瞧,这一切和new有啥关系呢?
    2. 我可以先Person p,再Student s,然后令 p=s,这样也没什么不好啊,也和new没啥关系。不知道我说的和你说的是不是一回事,你不要生气哈。我要是说的不正确,还望指教
      

  29.   


    java,说白了就是c++的简化版本,去掉了c++的复杂语法特征所谓java中的引用,相当于被阉割的指针——自动解引用,无法取指针值——但指针的基本特征依然存在之所以这么做,就是为了简化语法,简化编程
      

  30.   

    按照你的说法,Person p;这里的p指的是一个对象不是引用,请问你怎么把一个对象付给另外一个对象。这已经不是引用了。其实,从你这次的回复里可以看出来你已经有些理解了。如果你的理解p是个引用,s是对象的话,那么,你所说的这些东西,除了名字不叫new,和Java的new关键字代表的作用又有什么区别呢?只不过,我们肯定需要有一个区别来表明,这是引用,这是对象。引用和对象的概念是Java封装,多态等概念及特点的基础!这两个概念必须要分别开来,才能实现这两个功能。要知道,Java作为一门编程语言,最开始是被Sun公司内部的人士使用,如果楼主说的方法真的可行的话,他们应该早就用了。而他们不用就一定有他们的道理的。
      

  31.   

    相当同意#31楼的看法,我也觉得Java设计的初衷是为了在C++的基础上更方便的编程,所以才会想,既然能简化,干脆进一步简化,呵呵。
      

  32.   


    #32楼,谢谢你的肯定。
    我从一开始就没搞混淆。我记得书上说了,Java里,非内置类型,定义出来全部是引用,所以我一直没把他们当成对象,本帖一开始,我就当作是引用的,而new出来的那玩意才是对象,而我的意思则是,编译器不要我们写new,也主动自行弄个对象出来,我们定义的呢,依然是引用,但是由编译器自行和它弄出来的对象绑定了。所以,我觉得Java在试图减少“指针”概念的同时,其实就是想淡化“引用”和“对象”的界限。然而,new关键字一出,注定“引用”和“对象”是两个概念,还是得分开理解。所以我才说,干脆new不要得了。其实多态的时候,传来传去,都是引用,又没人把整个对象(实际的一片内存区域)传递,对不对。Java是个还在发展的语言,他们为啥不去掉new,我也不知道,不过从Java发展史来看:
    1.早期就一个垃圾回收,但后来发展出很多不同于C++的特色——这个不妨看作进化
    2.早期java的模板使用好像是不用指定类型的,现在最新的好像也得指定了——这个不妨又看作不得不靠拢C++的例子。所以,正因为它还在变化,不是一尘不变的,所以我才提出这个可能性供大家讨论的。谢谢你,我觉得大家在这个问题上陪我费这么多口舌,40分似乎都太少了,一会儿加点分吧
      

  33.   

    那请问你觉得虚拟机怎么创建对象捏?呵呵!无论怎样,这个对象是一定要创建的。虚拟机创建也是需要new这个关键字的!好了!大家讨论不是为了分数,只是为了交流嘛
      

  34.   


    嗯嗯,呵呵,一会儿给你分哈。虚拟机创建对象,你想啊,完全可以它自己控制,对不?
    1.它高兴了,告诉大家——你们用new我才创建,不用的话,哼哼,我不创建
    2.如果它听我的建议,决定修改了,于是告诉大家——算了,虚拟机我自己内部机制改改,以后大家不用new,直接用Person p;创建引用的时候,我就内部自动给大家申请一片内存(也即对象),并帮大家把p和这片内存绑定好就行了你瞧,呵呵,还不是Java的人,自己把虚拟机修改修改,就可以了,对不?
      

  35.   

    这语言不能只看技术,毕竟是英语的表达方式,可能设计者觉加new更符合英语的表达习惯。
      

  36.   

    thing in java 是什么书?
      

  37.   

    开什么玩笑。楼上大部分都是菜鸟吧。还讨论得煞有其事。取消了new,直接 type instance就表示了type instance = new type();那我空指针咋办啊。难道程序里面从头到尾都不需要空指针。
    你真当java的那帮老头是闲的蛋疼没事干,多整两个关键字给你背背啊。鄙视之
      

  38.   

    看了33楼俺恍然大悟,原来java是在c++基础上发展而来的啊
      

  39.   


    引用“thinking in java”里的一句话
    ——Although it is based on C++, Java is more of a “pure” object-oriented language.
      

  40.   

    可能把“指针”的概念去掉吗?
    最基本的数据结构链表怎么实现?
    想去除,先把java满世界的句柄(“指针”)干掉再说
      

  41.   


    Java的一个目标或许是“尽可能”消除“指针”、“引用”这些概念,为什么呢?就是为了让程序员尽量从这些概念中解放出来,专注于程序的逻辑。这个消除,说了,是“尽可能”,不是已经没有“*”这种符号,和“->”了吗?我考虑的是Java打算的方向,和眼下已经达到的程度,很多人却和楼上一样,喜欢根据“现状”来总结一些事实,并以为就是最终的形态。还是请先理解“讨论”的含义,以及打算“讨论”的思想,再回帖吧,免得白费不必要的精力,来解释我们到底要“讨论”什么啊,呵呵
      

  42.   


    我建议楼主去看一本书,名字叫做HeadFirst Java。这本书很受sun公司的推崇,而这本书的开头就花了一章来讲述new的重要性。还有,你一直说的Java的一个目标是尽可能消除指针和引用。现在我告诉你这是不可能的,因为如果Java的目标是消除引用变量的话,也不会在引用这个概念的基础上形成自己最重要的特点封装和多态了。这是Java面向对象的一大特点,也是Java最重要的优点。当然,不排除Oracle将来会对Java做重大改革,但是如果我在这里可以这样保证,如果将来Oracle不顾Java程序员的反对抛弃了Java这个优点,我宁愿重头再来,也不会再做Java程序员。
      

  43.   


    好的,你说的这本书我也下了电子版,稍后我去读一读。
    此外,我表达上可能有点问题,我的意思,并非是说Java企图尽可能“消除指针和引用”,我想说的是,Java或许是想尽可能“消除指针和引用这些概念”,就是说Java内部毫无疑问是在采用这些机制,但是对外暴露给程序员的,甚至教大家编写程序的时候,可以完全不用理会这些概念。而我一直想表达的意思就是,Java如何能够在内部使用这些机制的同时,更好的,不对外暴露,隐藏起来。我希望,哪天,当我不知道Java在默默的使用这些“优点”的时候,依然可以更简单快捷的写出好的Java程序,呵呵。
      

  44.   

    楼主先去看了那本书再说吧!还有,封装,多态,不是Java自己使用的有点,是暴露给我们,让我们使用的优点。由此才有了设计模式,依赖注入,面向切面编程,等等一系列概念的提出。而这些概念,不仅仅是概念,是我们正在使用的东西。如果楼主想要做一个Java程序员,就必须理解这些东西,别整天想着怎么让这些东西消失了。
      

  45.   

    那取消后创建对象的语法是Person p 还是 Person p = Person() ?这俩种都不好。
    第一中上面的前辈已经说过,会造成null赋值的不可用,因为创建引用的同时对象就已经新建好了,引用不能为空。而实际coding中null值很常用且很有用。
    第二种其实上面也有人说过。Java编译器无法组织在Person类外有一个方法名叫Person。就是说Person p = Person()无法确定是创建了一个空参的Person对象还是通过Person()方法返回了一个Person对象
      

  46.   

    老实说,我非常讨厌指针。我认为带有指针的东西是更加底层的、更接近机器语言的东西。Java是相对比较接近人类语言的东西。
      

  47.   

    好吧,这个问题,我不再参与讨论了……这两天,尝试了解了一些其他语言,感觉仅仅拿Java与C和C++对比,是一件很幼稚的事情,眼界很狭窄,例如,可以看看网上对于Lisp语言的介绍。只能说要学的东西太多了……不能纠结于这种问题不放