为什么java中的构造函数没有返回类型? [英] Why do constructors in java not have a return type?

查看:147
本文介绍了为什么java中的构造函数没有返回类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

为什么构造函数不返回值

有返回类型,甚至无效?

Why don't constructors have a return type, not even void? What's the reason for that?

推荐答案

构造函数在内部是一个非静态方法,名称 init> void 返回类型。它不返回任何东西。在内部第一个对象被分配,然后调用它的构造函数。对象不是用构造函数本身分配的。

换句话说,语法 new Object()不仅调用构造函数,而且创建新对象构造函数返回它。 Suns'Java教程表示遵循新操作符通过调用一个构造函数,它初始化新的对象。初始化并不意味着创建。

Constructor is internally a nonstatic method with name <init> and void return type. It does not return anything. Internally first object is allocated and then its constructor is called. Object is not allocated with constructor itself.
In other words the syntax new Object() not only calls the constructor but also creates new object and after calling the constructor returns it. The Suns' Java tutorial stands that "The new operator is followed by a call to a constructor, which initializes the new object." Initialize does not mean create.

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

Answering the question. Missing return type declaration is a way in which you distinguish the constructor from a method. But you can return from constructor as from void method. For example this code compiles and runs correctly:

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


$ b b

这个类有一个void方法(不要在家里尝试 - 大写方法是一个坏样式)和一个构造函数。

This class has one void method (don't try it at home - uppercase method is a bad style) and one constructor. The difference is in declared return type.

看看这个JNI代码片段,它表明构造函数是一个非静态的void方法:

Look at this JNI code snippet which demonstrates that constructor is a nonstatic void method:

 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方法)。

first object is allocated and then nonstatic <init> method is called. For details look here. The AllocObject function documentation stands that "Allocates a new Java object without invoking any of the constructors for the object. Returns a reference to the object." So in JVM object is not allocated by constructor, but only initialized by it. Looking in constructors' bytecode we are seeing that no object is returned (exactly like in void methods).

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

Another way, when you dissasemble sample class, you will see invocation of parent (Object) constructor from its constructor:

#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)详细描述了初始化的顺序和发生的时间,但是没有说明它是如何实现的。

Note that the <init> method is not actually part of the Java language. Rather, it is something the Java virtual machine expects to see in a Java class file. This distinction is significant because the Java language does not depend on the class file. Java source can be compiled into other binary formats, including native executables. A Java compiler that translates Java language source into some other binary format need not generate a method named <init>, so long as objects are initialized in the proper way at the proper time. The Java Language Specification (JLS) details the order of initialization and when it occurs, but doesn't say how it is actually accomplished.

但是我看到

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

For some of nonbelievers this is example (thx biziclop) which shows that object exists and is allocated before returning from constructor:

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

这篇关于为什么java中的构造函数没有返回类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆