Java初学,这种问题贻笑大方了,还请各位大侠不吝指教。 我学的还不深,似乎Java 所有的对象定义都使用,诸如 Myclass mc=new Myclass()的语句,相当开辟了一片内存,同时返回了指向这片内存的指针(Java喜欢说是句柄,引用)。 既然所有的定义,都这么干,那作为一个语种,就把new关键字取消好了,这种事情让编译器自己知道不就可以了?为什么还要有这个关键字呢?
调试欢乐多
名字而已哎,如果编译器不用大家显示的使用new,自动的默默的分配好了内存。那么new就给大家随便拿来当变量有什么不可以呢?
所以说我可能基础还不够啊,呵呵。不过你说的这是什么意思?难道,你的意思是单单一句“MyClass mc;”可能存在二义性?除了表示声明,还可能表示调用构造函数?还是说,你觉得不用new,没法传递参数给构造函数了?用Myclass mc(TYPE);不就行了?
语法,就是一种规范,java虚拟机可以解析的规范。
木有规范,给虚拟机造成强大的压力,硬是要虚拟机通过好多种方案中选出一种可以和你臆想的方案相匹配,这在性能上要很大的代价。你是要性能还是要写代码方便?要性能学机器语言/汇编/c。
要方便,貌似也没用绝对的方便。不过现在的很多语言正往这方向发展.而且很多方便也有局限性,也只是某一领域上有很方便,其他方面又很不方便。
如下代码:
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()?
你要考虑到,用户可能只是声明变量,并不想马上生成对象,需要的时候再生成对象
如果MyClass mc马上就生成对象了,那么对于有条件创建对象来说,就会造成过多的垃圾
比如
MyClass mc; //如果没有关键字,这里就会生成一个无意义的对象,
//如果是带参数的,参数又是动态的并且是个很复杂的对象无法直接用代码代替,那么该如何声明
if (contidion1) {
mc = new MyClass(arg1); //所以保留new,给用户一定的自由空间,才是有意义的
} else {
mc = new MyClass(arg2);
}
new是一个关键字,也是一个运算符,他要告诉jvm在遇到他的时候知道要去做什么事情,如果没有这个new运算符jvm怎么知道你是要创建一个对象的呢
1. Test t或者Test t()表示创建一个对象的引用(自然会调用构造函数)
2. Test t=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,给用户创建对象的自由,才是有意义的
我已经说过,这会有很多问题的Test t这种,在c++中,是可以创建对象的,且t不是指针类型如果假设t为引用(阉割的指针)
那么我想要声明一个t变量,指向null该怎么办?
Student extends Person;Person p = new Student();
如果木有new,你的p只能定义成Person的实例,不能有上面那种写法。
而多态是java的重要特性,灵活性很高。你这么做,就把多态给封杀了,为了一句简单的便利,付出代价是惨痛的。
这样做不会影响 多态性 机制吧? 至少我觉得:
1.父类引用子类对象,这个不影响,毕竟父类引用指向的内存区域不会超过子类对象内存的范围
2.如果说的是后期动态绑定,应该是java虚拟机记录了些信息,才能在“后期”做到,那么现在没有new,虚拟机依旧可以记录,信息量不会变少的。再次声明,仅仅讨论而已,呵呵,其实已经对各位大侠很是佩服了,讨论才有进步,对不:)
嗯,我刚才也在想,如果自动分配区域了,想让他指向NULL怎么办……好像Java就没打算定义过指向NULL的引用吧?? 之前看书的时候,好像脑子里就有这个疑问……当时的理解是,反正有个垃圾回收器,一旦回收了,且引用的作用范围早已不在的时候,也就无所谓去手动NULL了。
也因此,更没必要一开始就NULL了。
不知我的理解对不对
谢谢你 #17 楼,你的这个例子,正式Java的独创性给我带来的困惑,基于Java眼下已有的机制,你的代码,我就不讨论没有new该怎么说了,否则又会有向C++靠齐的嫌疑。不过,在C++中,确实也有这样的问题:如下代码可以编译通过,而注释的那一行,开放注释(去掉注释符)则编译不过了-_-|||#include <iostream>class A{};A A(A aa)
{
return aa;
}int main()
{
//A ee; //此行去掉注释符,则编译不过了
return 0;
』
FileInputStream fis = null;
try {
fis = new FileInputStream(System.in);
reader = new BufferedReader(fis);.....
} fianlly {
if(reader !=null) {
//close...
}
...
}
还有数据库操作,基本都是这么个try..finally模式
你说的没错,其实不仅仅是数组,形参如果是非内置类型,那么方法里可能还是要进行是否null的判断。我在想,我起初问这个问题,是因为隐约觉得,Java似乎希望把“指针”相关的概念都屏蔽掉。因此我才会觉得new、null这种带有“指针”痕迹的东西都能内部封装,或许才叫完美吧。不知道Java后续的版本会怎样发展……我继续看书了,谢谢各位大侠。
哎?你这个说的是什么意思?这里,你说的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没啥关系。不知道我说的和你说的是不是一回事,你不要生气哈。我要是说的不正确,还望指教
java,说白了就是c++的简化版本,去掉了c++的复杂语法特征所谓java中的引用,相当于被阉割的指针——自动解引用,无法取指针值——但指针的基本特征依然存在之所以这么做,就是为了简化语法,简化编程
#32楼,谢谢你的肯定。
我从一开始就没搞混淆。我记得书上说了,Java里,非内置类型,定义出来全部是引用,所以我一直没把他们当成对象,本帖一开始,我就当作是引用的,而new出来的那玩意才是对象,而我的意思则是,编译器不要我们写new,也主动自行弄个对象出来,我们定义的呢,依然是引用,但是由编译器自行和它弄出来的对象绑定了。所以,我觉得Java在试图减少“指针”概念的同时,其实就是想淡化“引用”和“对象”的界限。然而,new关键字一出,注定“引用”和“对象”是两个概念,还是得分开理解。所以我才说,干脆new不要得了。其实多态的时候,传来传去,都是引用,又没人把整个对象(实际的一片内存区域)传递,对不对。Java是个还在发展的语言,他们为啥不去掉new,我也不知道,不过从Java发展史来看:
1.早期就一个垃圾回收,但后来发展出很多不同于C++的特色——这个不妨看作进化
2.早期java的模板使用好像是不用指定类型的,现在最新的好像也得指定了——这个不妨又看作不得不靠拢C++的例子。所以,正因为它还在变化,不是一尘不变的,所以我才提出这个可能性供大家讨论的。谢谢你,我觉得大家在这个问题上陪我费这么多口舌,40分似乎都太少了,一会儿加点分吧
嗯嗯,呵呵,一会儿给你分哈。虚拟机创建对象,你想啊,完全可以它自己控制,对不?
1.它高兴了,告诉大家——你们用new我才创建,不用的话,哼哼,我不创建
2.如果它听我的建议,决定修改了,于是告诉大家——算了,虚拟机我自己内部机制改改,以后大家不用new,直接用Person p;创建引用的时候,我就内部自动给大家申请一片内存(也即对象),并帮大家把p和这片内存绑定好就行了你瞧,呵呵,还不是Java的人,自己把虚拟机修改修改,就可以了,对不?
你真当java的那帮老头是闲的蛋疼没事干,多整两个关键字给你背背啊。鄙视之
引用“thinking in java”里的一句话
——Although it is based on C++, Java is more of a “pure” object-oriented language.
最基本的数据结构链表怎么实现?
想去除,先把java满世界的句柄(“指针”)干掉再说
Java的一个目标或许是“尽可能”消除“指针”、“引用”这些概念,为什么呢?就是为了让程序员尽量从这些概念中解放出来,专注于程序的逻辑。这个消除,说了,是“尽可能”,不是已经没有“*”这种符号,和“->”了吗?我考虑的是Java打算的方向,和眼下已经达到的程度,很多人却和楼上一样,喜欢根据“现状”来总结一些事实,并以为就是最终的形态。还是请先理解“讨论”的含义,以及打算“讨论”的思想,再回帖吧,免得白费不必要的精力,来解释我们到底要“讨论”什么啊,呵呵
我建议楼主去看一本书,名字叫做HeadFirst Java。这本书很受sun公司的推崇,而这本书的开头就花了一章来讲述new的重要性。还有,你一直说的Java的一个目标是尽可能消除指针和引用。现在我告诉你这是不可能的,因为如果Java的目标是消除引用变量的话,也不会在引用这个概念的基础上形成自己最重要的特点封装和多态了。这是Java面向对象的一大特点,也是Java最重要的优点。当然,不排除Oracle将来会对Java做重大改革,但是如果我在这里可以这样保证,如果将来Oracle不顾Java程序员的反对抛弃了Java这个优点,我宁愿重头再来,也不会再做Java程序员。
好的,你说的这本书我也下了电子版,稍后我去读一读。
此外,我表达上可能有点问题,我的意思,并非是说Java企图尽可能“消除指针和引用”,我想说的是,Java或许是想尽可能“消除指针和引用这些概念”,就是说Java内部毫无疑问是在采用这些机制,但是对外暴露给程序员的,甚至教大家编写程序的时候,可以完全不用理会这些概念。而我一直想表达的意思就是,Java如何能够在内部使用这些机制的同时,更好的,不对外暴露,隐藏起来。我希望,哪天,当我不知道Java在默默的使用这些“优点”的时候,依然可以更简单快捷的写出好的Java程序,呵呵。
第一中上面的前辈已经说过,会造成null赋值的不可用,因为创建引用的同时对象就已经新建好了,引用不能为空。而实际coding中null值很常用且很有用。
第二种其实上面也有人说过。Java编译器无法组织在Person类外有一个方法名叫Person。就是说Person p = Person()无法确定是创建了一个空参的Person对象还是通过Person()方法返回了一个Person对象