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

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

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

3 Solutions collect form web for “Почему конструкторы в 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 не должна возвращать какое-либо значение, на практике это вроде как – ссылка на новый объект. Тогда это было бы синтаксически странно и / или сбивать с толку, чтобы иметь возможность хранить одну или обе ссылки на новый объект и дополнительное возвращаемое значение в одном выражении.

  • Как получить имена параметров конструкторов объекта (reflection)?
  • В любом случае, @Autowire bean, который требует аргументов конструктора?
  • Не может ли тип C ++ POD иметь какой-либо конструктор?
  • Вызов виртуальных функций внутри конструкторов
  • Структурный конструктор в C ++?
  • Сеттерные методы или конструкторы
  • Как начать намерение, передав ему некоторые параметры?
  • механизм вызова конструктора
  • Синхронизация конструктора в Java
  • Конструкторы Java
  • тривиальный или стандартный макет против POD
  • Interesting Posts

    Почему нет возможности комбинировать псевдо-элементы / classы, относящиеся к конкретному поставщику, в один набор правил?

    Восстановите MacBook Pro до заводских настроек без диска

    Алгоритм определения периодов перекрытия

    Как установить текущий рабочий каталог?

    Лучший способ сохранить чернила в струйном принтере, когда их редко используют?

    Каков самый быстрый способ высокопроизводительного последовательного ввода-вывода файлов в C ++?

    Не удалось создать Android Virtual Device

    Получить только запрошенный элемент в массиве объектов в коллекции MongoDB

    Правильность алгоритма Сакамото, чтобы найти день недели

    Как надежно сохранить SSH-туннель открытым?

    Неправильная публикация ссылки на объект Java

    Java 8 метод ссылки необработанное исключение

    Есть ли разница между инициализацией копирования и прямой инициализацией?

    Что делает «задержка запуска» в типе запуска для службы Windows?

    Как получить идентификатор самого верхнего действия?

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