我在网上浏览了Java中"new"的用法,它是用来创建一个全新的类实例的.为什么这需要通过"new"关键字进行明确指示?难道还不能理解构造函数调用实例化新对象吗?例如,如果没有new
,MyClass AnInstance = MyClass(AnArgument)
显然会创建一个新对象.
从实践的Angular 来看,我问这个问题的原因是,我认为"新"是为了防止危险而设计的,而我想要意识到危险.
我在网上浏览了Java中"new"的用法,它是用来创建一个全新的类实例的.为什么这需要通过"new"关键字进行明确指示?难道还不能理解构造函数调用实例化新对象吗?例如,如果没有new
,MyClass AnInstance = MyClass(AnArgument)
显然会创建一个新对象.
从实践的Angular 来看,我问这个问题的原因是,我认为"新"是为了防止危险而设计的,而我想要意识到危险.
这是一个名称空间的问题.
在Java中,方法和字段可以具有相同的名称,并且它们完全不相关.事实上,类型也可以,包裹也可以.所有4个都是完全正交的.Never the 4 shall meet:
package foo;
public class foo {
int foo;
public foo() { /* constructor */ }
public void foo() { /* method */ }
}
这是entirely个合法的.这里没有任何东西覆盖任何东西--这是包foo
中一个名为foo
的类,有3个成员:一个名为foo
的字段,一个不接受任何参数的构造函数,以及一个不接受任何参数也不返回任何内容的foo
方法.你可以编译它.它会的.没有任何警告.您的IDE可能会抱怨以小写字母开头的文字不符合常规.但这只是惯例.Lang规范允许这样做.javac
将很好地编译上述内容.
那么,如果你可以将所有这些东西都命名为同一个东西,那么这是如何运作的呢?
从上下文中,Java总是知道您在做什么.
在某些语言中,在调用方法时,括号是可选的,或者至少所有内容都在同一个名称空间中.
例如,在Java脚本中:
function test() {
}
var x = test;
是合法的;x
现在是对test
函数的引用.
这也意味着你cannot,事实上,有一个方法和一个变量在JavaScript中具有相同的名称:
function test() {
}
test = 5;
test();
不起作用.最后一条语句try 将"5"作为函数执行,但它不是.
在Java中情况并非如此(这些花括号不是可选的,没有花括号,它就不是关于那个方法,句号),因为Java有4个完全不相关的命名空间,这在某种程度上是独一无二的.
因此,new
-MUST指数为什么会存在.因为如果它不在那里,Java就不知道要挖掘两个相关名称空间(类型和方法)中的哪一个.换句话说,这是:
public class Test {
public Test() {}
public static void Test() {}
}
是合法的Java .它编译得很好.那么,如果导入这个测试类,然后写下:Test();
,那么我指的是哪一个呢?
在Java中,很明显:如果你写new Test()
,它就是构造函数,如果你写Test()
,它就是静态方法.
我们可以详细讨论拥有正交名称空间是否是明智的 idea .然而,Java不喜欢 destruct 向后兼容性,at this point改变它显然不值得为此付出痛苦,因此您的问题将归结为:"为什么Java的设计者在30年前就决定使用正交名称空间?"在这样一个问题上很难回答,我需要一根鞭子和一顶棕色帽子,还有一些约翰·威廉姆斯的音乐.
在类级别,这些构造函数被编译为特殊方法,它们的行为大多类似于静态方法(因为它们不做虚拟查找,也不需要接收器-它与静态方法共享属性,而不需要实例方法),命名为<init>
.第Test
章不管你叫什么名字
因此,最好考虑它们(因为它实际上就是这样工作的):
void
个--或者声明一个方法!)--但这只是为了让编译器知道您在做什么.考虑到重复您的类型的名称是Java避免引入关键字的方法(它可能是public constructor(String arg1, int arg2)
而不是public TypeNameGoesHere(String arg1, int arg2)
,但它不是.同样,30年,如果我们想深入了解原因,请躲避一些蛇).注:名称空间实际上是相遇的.它在SELECT AST Chains中:a.b.c.d.e
是不明确的:包a.b
,然后是类型c
,具有名为d
的静态内部类型,并且具有名为e
的静态字段?或者它是包a
,具有类b
、内部类c
、静态字段d
,其类型z
具有名为e
的实例字段?
Javac在编译期间在黑暗中进行了最好的try ,并将其"锁定".在运行时(类文件)级别,命名空间确实不能满足.每条指令都明确标识符引用的是4个命名空间中的哪一个.