为什么在java中的构造函数没有返回types?

可能重复:
为什么构造函数不返回值

为什么构造函数没有返回types,甚至没有void? 这是什么原因?

构造函数在内部是一个名称为<init>void返回types非静态方法 。 它不会返回任何东西。 内部第一个对象被分配,然后调用它的构造函数。 对象不是用构造函数本身分配的。
换句话说, new Object()语法不仅可以调用构造函数,还可以创build新对象,并在调用构造函数之后返回它。 太阳的Java教程表示:“新操作符后面是一个构造函数的调用,它初始化新的对象。 初始化并不意味着创build。

回答这个问题。 缺less返回types声明是区分构造函数和方法的一种方式。 但是你可以从void方法返回构造函数。 例如,这段代码编译并正确运行:

 public class TheClass { public TheClass(){ return; } public void TheClass(){ //confusing, but this is void method not constructor return; } public static void main(String[]a){ TheClass n = new TheClass(); n.TheClass();//void method invocation } } 

这个类有一个void方法( 不要在家里尝试 – 大写方法是一个糟糕的风格)和一个构造函数。 区别在于声明的返回types。

看看这个JNI代码片断,它演示了构造函数是一个非静态的void方法:

  jstring MyNewString(JNIEnv *env, jchar *chars, jint len) { jclass stringClass; jmethodID cid; jcharArray elemArr; jstring result; stringClass = (*env)->FindClass(env, "java/lang/String"); if (stringClass == NULL) { return NULL; /* exception thrown */ } /* Get the method ID for the String(char[]) constructor */ cid = (*env)->GetMethodID(env, stringClass, "<init>", "([C)V"); if (cid == NULL) { return NULL; /* exception thrown */ } /* Create a char[] that holds the string characters */ elemArr = (*env)->NewCharArray(env, len); if (elemArr == NULL) { return NULL; /* exception thrown */ } (*env)->SetCharArrayRegion(env, elemArr, 0, len, chars); result = (*env)->AllocObject(env, stringClass); if (result) { (*env)->CallNonvirtualVoidMethod(env, result, stringClass, cid, elemArr); /* we need to check for possible exceptions */ if ((*env)->ExceptionCheck(env)) { (*env)->DeleteLocalRef(env, result); result = NULL; } } /* Free local references */ (*env)->DeleteLocalRef(env, elemArr); (*env)->DeleteLocalRef(env, stringClass); return result; } 

特别是这些片段:

  /* Get the method ID for the String(char[]) constructor */ cid = (*env)->GetMethodID(env, stringClass, "<init>", "([C)V"); 

接着

  /* Allocate new object. */ result = (*env)->AllocObject(env, stringClass); if (result) { /* Call uninitialized objects' constuctor. */ (*env)->CallNonvirtualVoidMethod(env, result, stringClass, cid, elemArr); 

第一个对象被分配,然后调用非静态的<init>方法。 详情请看这里 。 AllocObject函数文档表示:“分配一个新的Java对象,而不调用对象的任何构造函数,返回对该对象的引用”。 所以在JVM中,对象不是由构造函数分配的,而只是由它初始化的。 查看构造函数的字节码,我们看到没有对象返回(就像在void方法中一样)。

另一种方法,当你解散样本类时,你会看到它的构造函数调用父(Object)构造函数:

 #javap -c NewClass Compiled from "NewClass.java" public class NewClass extends java.lang.Object{ public NewClass(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return } 

请注意, <init>方法实际上并不是Java语言的一部分。 相反,这是Java虚拟机期望在Java类文件中看到的东西。 这种区别很重要,因为Java语言不依赖于类文件。 Java源代码可以编译为其他二进制格式,包括本地可执行文件。 一个将Java语言源代码翻译成其他二进制格式的Java编译器,只要在适当的时候以适当的方式初始化对象,就不需要生成一个名为<init>的方法。 Java语言规范(JLS)详细说明了初始化的顺序以及何时发生,但并没有说明它是如何实际完成的。

但是我看到我们在这里正在讨论JVM。

对于一些非信徒来说,这是一个例子(thx biziclop),它显示了对象的存在,并在从构造函数返回之前被分配:

  class AnotherClass { private String field; public static AnotherClass ref; public AnotherClass() { this.field = "value"; AnotherClass.ref = this; throw new RuntimeException(); } @Override public String toString() { return field; } } public class MainClass { public static void main(String[] a) { try { new AnotherClass(); return; } catch (RuntimeException ex) { System.out.println("exception"); } System.out.println("instance: " + AnotherClass.ref); } } 

你将如何得到返回的价值? 你感兴趣的是什么样的价值? 你将如何声明返回types?

  X x = new X (); 

为x指定一个X引用。 现在,如果new X会返回一些东西,你应该怎么得到它?

  class X { public int X () { return 42; } } 

什么是从ctor返回的东西的逻辑? 错误消息? 一些loginfo? 将它写入一个文件或者一个属性,稍后再进行轮询。

由于ctor只能访问每个对象一次,我可以想到的唯一的原因,使用另一个返回值,将通知创build过程本身。

  class X { private Y y; public int X () { y = new Y (); } public Y getY () { return y; } } 

即使构造函数的虚拟机实现不是要返回任何值,实际上它也是 – 新对象的引用。 如果能够在一个语句中存储一个或两个新对象的引用和一个额外的返回值,那么在语法上就会变得奇怪和/或令人困惑。