Почему конструкторы в java не имеют типа возврата?

Возможный дубликат:
Почему конструктор не возвращает значение

Почему у конструкторов нет типа возврата, даже не пусто? В чем причина этого?

Конструктор является внутренним нестатическим методом с именем и типом возврата void . Он ничего не возвращает. Внутренне первый объект распределяется, а затем вызывается его конструктор. Объект не выделяется самим конструктором.
Другими словами, синтаксис new Object() не только вызывает конструктор, но также создает новый объект и после вызова конструктора возвращает его. Учебник Java Suns утверждает, что «за новым оператором следует вызов конструктора, который инициализирует новый объект». Инициализация не означает создание.

Отвечая на вопрос. Недопустимая декларация типа возврата – это способ, которым вы выделяете конструктор из метода. Но вы можете вернуться из конструктора, как из метода 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 } } 

Этот class имеет один метод void ( не пытайтесь его дома – метод верхнего регистра – плохой стиль) и один конструктор. Разница заключается в объявленном типе возврата.

Посмотрите на этот fragment кода 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, "", "([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; } 

особенно эти fragmentы:

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

а потом

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

первый объект выделяется, и затем вызывается нестатический метод . Подробнее смотрите здесь . В документации по функциям AllocObject указано, что «Выделяет новый объект Java без вызова каких-либо конструкторов для объекта. Возвращает ссылку на объект». Таким образом, объект JVM не выделяется конструктором, а только инициализируется им. Глядя на байт-код конструкторов, мы видим, что объект не возвращается (точно так же, как в методах void).

Другой способ, когда вы разбираете образец classа, вы увидите вызов родительского (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."":()V 4: return } 

Обратите внимание, что метод самом деле не является частью языка Java. Скорее, это то, что ожидает виртуальная машина Java в файле classа Java. Это различие имеет большое значение, поскольку язык Java не зависит от файла classа. Источник Java может быть скомпилирован в другие двоичные форматы, включая собственные исполняемые файлы. Компилятор Java, который переводит источник языка Java в какой-то другой двоичный формат, не должен генерировать метод с именем , если объекты инициализируются надлежащим образом в соответствующее время. Спецификация языка 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); } } 

Как вы получите возвращаемое значение? Какую ценность вы интересуете, возвращаетесь? Как бы вы объявили тип возврата?

  X x = new X (); 

назначает X-ссылку на x. Теперь, если new X вернет что-то, как вы его получите?

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

Какова логика возврата чего-то из ctor? Сообщение об ошибке? Некоторые loginfo? Напишите его в файл или в атрибут, который вы опросите позже.

Поскольку ctor доступен только один раз для объекта, единственной причиной, по которой я могу думать, использовать другое возвращаемое значение, было бы, чтобы сообщить о процессе создания.

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

Несмотря на то, что реализация конструктора VM не должна возвращать какое-либо значение, на практике это вроде как – ссылка на новый объект. Тогда это было бы синтаксически странно и / или сбивать с толку, чтобы иметь возможность хранить одну или обе ссылки на новый объект и дополнительное возвращаемое значение в одном выражении.

  • Что это за странный синтаксис двоеточия (":") в конструкторе?
  • Вызов виртуальных функций внутри конструкторов
  • Почему это () и super () должны быть первым утверждением в конструкторе?
  • Могут ли конструкторы быть асинхронными?
  • Анонимный союз C ++ 11 с нетривиальными членами
  • Методы против конструкторов в Java
  • Построение конструктора копирования в Java
  • Конструктор Date (...) устарел. Что это значит? (Ява)
  • Могут ли конструкторы исключать исключения из Java?
  • Конструктор по умолчанию с пустыми скобками
  • Каково использование статических конструкторов?
  • Interesting Posts

    Как регистрировать производительность всех процессов в Windows 7?

    Что происходит, когда заканчиваются все IP-адреса?

    Каков наилучший способ преобразования между char * и System :: String в C ++ / CLI

    Как я могу изменить ярлык по умолчанию в Windows для закрытия программ?

    Получать текстовое содержимое со страницы mediawiki через API

    Как использовать Zxing в android

    Почему я спрашиваю «Вы уверены, что хотите скопировать этот файл без его свойств?» При копировании файлов с NTFS на диск FAT?

    Как показать определенную часть изображения в javafx

    Выполняется ли Android-сервис из отдельного streamа вместо пользовательского интерфейса?

    Получить подписи экспортируемых функций в DLL

    Извлечение имени вызывающего метода из метода

    Использование scanner.nextLine ()

    Командная строка как пользователь SYSTEM (Windows 7)

    Права администратора для одного метода

    Извлечение файла со слишком длинным именем

    Давайте будем гением компьютера.