их всего 3: обычный c-tor (новое ключевое слово), clone () и Unsafe.allocateInstance(Class). Остальные называют одним из таких. Отражение компилируется в вызов c-tor, десериализация в Unsafe.allocateInstance (Class). Вы можете создать свой собственный API, и в итоге вы вызовете один из них.
bestsss
2
@ bestsss- Unsafeэто специфическая для реализации деталь Java и не упоминается нигде в спецификации. Вполне возможно построить послушную реализацию Java , которая не использует компиляцию отражения вниз к коду , который использует new, cloneили Unsafe.allocateInstance.
Существует четыре различных способа создания объектов в Java:
. Использование newключевого слова
Это наиболее распространенный способ создания объекта в Java. Почти 99% объектов созданы таким образом.
MyObject object =newMyObject();
B . Использование Class.forName()
Если мы знаем имя класса и если у него есть открытый конструктор по умолчанию, мы можем создать объект таким способом.
Таким образом, на самом деле существует только 2 способа: вызов конструктора (с использованием new, clone () или отражения) и десериализация, которая не вызывает конструктор.
AlexR
13
@AlexR: Object.clone()тоже не вызывает конструктор.
Axtavt
1
Поскольку это, кажется, ответ на самом верху, не могли бы вы добавить создания массивов в качестве подслучаев для A и B? (Смотрите мой ответ для деталей).
Паŭло Эберманн
Десериализация вызывает конструктор, но не самого производного типа.
Том Хотин - tackline
2
Вы должны также упомянуть Constructorкласс, который обобщает Class.newInstance.
templatetypedef
68
Есть разные способы:
Через Class.newInstance.
Через Constructor.newInstance.
Посредством десериализации (использует конструктор без аргументов наиболее производного несериализуемого базового класса).
Через Object.clone( не вызывает конструктор ).
Через JNI (должен вызывать конструктор).
С помощью любого другого метода, который вызывает newдля вас.
Я предполагаю, что вы могли бы описать загрузку классов как создание новых объектов (таких как interned Strings).
Литеральный массив как часть инициализации в объявлении (нет конструктора для массивов).
Массив в ...вызове метода varargs ( ) (без конструктора для массивов).
Некомпиляция конкатенации строк с постоянной времени (в типичной реализации происходит как минимум четыре объекта).
Вызывает исключение, которое будет создано и выдано средой выполнения. Например throw null;или "".toCharArray()[0].
Да и бокс примитивов (если не кешируется), конечно.
JDK8 должен иметь лямбды (по существу, краткие анонимные внутренние классы), которые неявно преобразуются в объекты.
Для полноты (и Paŭlo Ebermann) есть также некоторый синтаксис с newключевым словом.
@ Paŭlo Ebermann Это такая старая школа и не крутая. (Я предполагал, что то, что подразумевается под вопросом «использовать конструктор (хотя большинство, но не все, из вышеперечисленного действительно используют конструктор / a где-то вдоль линии).)
Том Хотин - tackline
на самом деле есть только 3 реальных способа сделать это, для которых я добавил комментарий
bestsss
3
Вы пропустили один: java.misc.Unsafe.allocateInstance(). Хотя это неприятно по ряду причин. И фактически, десериализация не использует конструктор без аргументов. Под капотом он использует allocateInstanceили эквивалентную черную магию.
Стивен С.
Лучший ответ пока, но JNI AllocObject().не вызывает конструктор.
Маркиз Лорн
25
В языке Java единственный способ создать объект - вызвать его конструктор, явным или неявным образом. Используя отражение в результате вызова метода конструктора, десериализация использует отражение для вызова конструктора, фабричные методы заключают вызов в конструктор, чтобы абстрагировать фактическую конструкцию, и клонирование аналогично является вызовом конструктора в оболочке.
Неправильно. Deserializatio не вызывает конструктор класса ни явно, ни неявно.
Маркиз Лорн
2
Я не должен был писать «его конструктор» и «конструктор», а скорее «конструктор» и «конструктор». В случае десериализации всегда вызывается первый применимый конструктор без аргументов.
Беспорядок
1
Реализация клона по умолчанию не вызывает никакого конструктора.
Дидье Л
если это моя реализация метода клона "return super.clone ();". Тогда он не будет вызывать конструктор.
Mateen
13
Да, вы можете создавать объекты с помощью отражения. Например, String.class.newInstance()даст вам новый пустой объект String.
4. Использование clone()метода → без вызова конструктора
Employee emp4 =(Employee) emp3.clone();
5. Использование десериализации → нет вызова конструктора
ObjectInputStream in =newObjectInputStream(newFileInputStream("data.obj"));Employee emp5 =(Employee) in.readObject();
Первые три newключевых слова методов и оба newInstance()включают вызов конструктора, но позже два метода клонирования и десериализации создают объекты без вызова конструктора.
Все вышеперечисленные методы имеют разные байт-коды, связанные с ними. Прочитайте различные способы создания объектов в Java с примером для примеров и более подробным описанием, например преобразование байт-кода всех этих методов.
Однако можно утверждать, что создание массива или строкового объекта также является способом создания объекта, но эти вещи более специфичны только для некоторых классов и обрабатываются непосредственно JVM, в то время как мы можем создать объект любого класса, используя эти 5 способов.
@stacker: Не могли бы вы объяснить, как это связано с созданием нового объекта? Спасибо.
ryanprayogo
4
@ryanprayogo clone () вернет новый объект (даже если этот объект является клоном объекта, к которому был вызван clone ()) и фактически является единственным способом создания нового объекта без вызова конструктора.
Томас Лётцер
6
Также вы можете десериализовать данные в объект. Это не проходит через конструктор класса!
ОБНОВЛЕНО : Спасибо, Том, за то, что указал на это в своем комментарии! И Майкл тоже экспериментировал.
Он проходит через конструктор самого производного несериализуемого суперкласса.
И когда у этого класса нет конструктора без аргументов, при десериализации генерируется исключение InvalidClassException.
Он проходит через конструктор (конструктор без аргументов наиболее производного несериализуемого суперкласса).
Том Хотин - Tackline
1
@ Том Ого, я этого не знал и немного поэкспериментировал. Очевидно, что когда самый производный несериализуемый суперкласс не имеет конструктора без аргументов, это приводит к тому, что InvalidClassException сериализуется в поток и генерируется при десериализации !! - Как странно это?
Майкл Боргвардт
6
Существует тип объекта, который не может быть создан обычными механизмами создания экземпляров (вызывающими конструкторами): массивы . Массивы создаются с
A[] array =new A[len];
или
A[] array =new A[]{ value0, value1, value2 };
Как сказал Шон в комментарии, это синтаксически похоже на вызов конструктора, и внутренне это не намного больше, чем выделение и инициализация нулями (или инициализация с явным содержимым, во втором случае) блока памяти, с некоторым заголовком для обозначения тип и длина.
При передаче аргументов в varargs-метод там тоже создается (и заполняется) массив неявно.
Четвертый способ будет
A[] array =(A[])Array.newInstance(A.class, len);
Конечно, клонирование и десериализация работает и здесь.
В Стандартном API есть много методов, которые создают массивы, но все они фактически используют один (или более) из этих способов.
Конечно, вы не можете определять конструкторы Array, но помимо этого механизм является тем же newключевым словом. Array.newInstance - единственный новый механизм здесь
Шон Патрик Флойд
@Sean: это то же самое ключевое слово, но это совершенно другой внутренний механизм, осмелюсь сказать.
Paŭlo Ebermann
Это правда, конечно. Но с другой стороны, разные версии создания массивов практически одинаковы. Только что понял, что ваш ответ был с 2011 года. Извините за разжигание старых вещей :-)
Шон Патрик Флойд
@Sean: Нет проблем, я воспользовался этим случаем, чтобы исправить грамматику.
Paŭlo Ebermann
отличная работа, никто не обсуждал здесь о массивах!
Матин
5
Другие способы, если мы исчерпывающие.
В Oracle JVM есть Unsafe.allocateInstance (), которая создает экземпляр без вызова конструктора.
Использование манипуляция байт - код , вы можете добавить код anewarray, multianewarray, newarrayили new. Они могут быть добавлены с использованием таких библиотек, как ASM или BCEL. Версия bcel поставляется с Oracle Java. Опять же, это не вызывает конструктор, но вы можете вызвать конструктор как отдельный вызов.
используя newоператор (таким образом вызывая конструктор)
используя отражение clazz.newInstance()(которое снова вызывает конструктор). Или clazz.getConstructor(..).newInstance(..)(снова используя конструктор, но вы можете выбрать, какой из них)
Резюмировать ответ - один из основных способов - вызывая конструктор класса объекта.
Обновление: в другом ответе перечислены два способа, которые не связаны с использованием конструктора - десерализация и клонирование.
(4) требуется только в том Class.forName()случае, если у вас еще нет класса, что во всех остальных случаях у вас есть. Он также не требует конструктора без аргументов: есть способы вызвать любой открытый конструктор, если вы знаете правильные аргументы. И вы оставили не менее двух других способов.
Маркиз Лорн
2
(2) Фабричный метод - это просто шаблон для получения объектов. Но внутри он использует «новое» ключевое слово для создания объектов.
Картик Бозе
Человек, почему так много людей говорят, что фабричный метод создает объекты, откуда вы, ребята, учились этому?
Матин
3
Вы также можете клонировать существующий объект (если он реализует Cloneable).
Используя новое ключевое слово. Это наиболее распространенный способ создания объекта в Java. Почти 99% объектов созданы таким образом.
Employee object =newEmployee();
Способ 2
Использование Class.forName (). Class.forName () предоставляет вам объект класса, который полезен для отражения. Методы этого объекта определяются Java, а не программистом, пишущим класс. Они одинаковы для всех классов. Вызов newInstance () для этого дает вам экземпляр этого класса (то есть, вызывающийClass.forName ("ExampleClass"). NewInstance () это эквивалентно вызову нового ExampleClass ()), в котором вы можете вызывать методы, которые определяет класс, доступ к видимым полям и т. д.
Class.forName () всегда будет использовать ClassLoader вызывающей стороны, тогда как ClassLoader.loadClass () может указывать другой ClassLoader. Я считаю, что Class.forName также инициализирует загруженный класс, тогда как подход ClassLoader.loadClass () не делает этого сразу (он не инициализируется, пока не будет использован в первый раз).
Другой должен прочитать:
Java: Введение в состояние потока с примером Простой пример перечисления Java
Способ 3
Использование clone (). С помощью clone () можно создать копию существующего объекта.
Использование десериализации объекта. Десериализация объекта - это не что иное, как создание объекта из его сериализованной формы.
// Create Object5// create a new file with an ObjectOutputStreamFileOutputStream out =newFileOutputStream("");ObjectOutputStream oout =newObjectOutputStream(out);// write something in the file
oout.writeObject(object3);
oout.flush();// create an ObjectInputStream for the file we created beforeObjectInputStream ois =newObjectInputStream(newFileInputStream("crunchify.txt"));Employee object5 =(Employee) ois.readObject();
Не используйте форматирование кода для текста, который не является кодом. Есть больше методов, чем эти. Прочитайте другие ответы. «Почти 99%» - это просто догадки.
Маркиз Лорн
Привет, EJP, извини за эту ошибку ... Я сказал, что это один из способов создания объектов, которые не совсем точно названы. Это просто модель. И извините, я alearner и новичок в stackoverflow
Андрия
0
С точки зрения пользователя API, другой альтернативой конструкторам являются статические фабричные методы (например, BigInteger.valueOf ()), хотя для автора API (и технически «для реального») объекты все еще создаются с использованием конструктора.
3 и 4 - разные псевдонимы для одного и того же механизма
Шон Патрик Флойд
-2
есть также ClassLoader.loadClass (string), но это не часто используется.
и если вы хотите быть абсолютным юристом по этому поводу, технически массивы являются объектами из-за свойства массива .length. поэтому инициализация массива создает объект.
loadClass (String name) возвращает результирующий объект Class, который является объектом yes, но не объектом этого класса. Если приведены примеры, то мы можем найти множество таких примеров в библиотеке java, но они будут специфичными для класса. проверьте youtu.be/gGGCmrD6Qpw
нанософт
-3
Мы можем создать объекты 5 способами:
новым оператором
отражением (например, Class.forName (), за которым следует Class.newInstance ())
Class.forName () загружает класс, а не создает объект.
Маркиз Лорн
отражение? Конечно, вы имеете в виду отражение.
Стивен С.
Как бы вы создали объект из метода фабрики, внутренняя реализация может снова использовать новое ключевое слово, верно? и почему у вас есть отражение дважды? Было бы больше смысла , если вы на самом деле дать некоторые exampls
Это способ создания примитивных типов данных, это просто гибкость, которую Java обеспечивает за кулисами, чтобы не использовать ключевое слово «new». Это то же самое, что и ключевое слово new.
Мадусуданан
Madhusudan, FYI, С помощью оператора new объекты всегда должны храниться в куче, в то время как в этом случае «Hello» - это объект, который должен храниться в пуле строк. И String - это класс, а не примитивный тип данных.
Дипак Шарма
Это не создает объект. Он присваивает ссылку на существующий объект. Объект уже был создан компилятором и загрузчиком классов.
Unsafe.allocateInstance(Class)
. Остальные называют одним из таких. Отражение компилируется в вызов c-tor, десериализация в Unsafe.allocateInstance (Class). Вы можете создать свой собственный API, и в итоге вы вызовете один из них.Unsafe
это специфическая для реализации деталь Java и не упоминается нигде в спецификации. Вполне возможно построить послушную реализацию Java , которая не использует компиляцию отражения вниз к коду , который используетnew
,clone
илиUnsafe.allocateInstance
.Ответы:
Существует четыре различных способа создания объектов в Java:
. Использование
new
ключевого словаЭто наиболее распространенный способ создания объекта в Java. Почти 99% объектов созданы таким образом.
B . Использование
Class.forName()
Если мы знаем имя класса и если у него есть открытый конструктор по умолчанию, мы можем создать объект таким способом.
C . Использование
clone()
Clone () можно использовать для создания копии существующего объекта.
D . Использование
object deserialization
десериализации объекта - это не что иное, как создание объекта из его сериализованной формы.
Вы можете прочитать их здесь .
источник
Object.clone()
тоже не вызывает конструктор.Constructor
класс, который обобщаетClass.newInstance
.Есть разные способы:
Class.newInstance
.Constructor.newInstance
.Object.clone
( не вызывает конструктор ).new
для вас.String
s)....
вызове метода varargs ( ) (без конструктора для массивов).throw null;
или"".toCharArray()[0]
.new
ключевым словом.источник
java.misc.Unsafe.allocateInstance()
. Хотя это неприятно по ряду причин. И фактически, десериализация не использует конструктор без аргументов. Под капотом он используетallocateInstance
или эквивалентную черную магию.AllocObject().
не вызывает конструктор.В языке Java единственный способ создать объект - вызвать его конструктор, явным или неявным образом. Используя отражение в результате вызова метода конструктора, десериализация использует отражение для вызова конструктора, фабричные методы заключают вызов в конструктор, чтобы абстрагировать фактическую конструкцию, и клонирование аналогично является вызовом конструктора в оболочке.
источник
Да, вы можете создавать объекты с помощью отражения. Например,
String.class.newInstance()
даст вам новый пустой объект String.источник
Есть пять разных способов создать объект в Java,
1. Используя
new
ключевое слово → конструктор получить вызов2. Используя
newInstance()
метод конструктораClass
→, вызываетсяЭто также можно записать как
3. Используя
newInstance()
методConstructor
→ constructor, вызывается4. Использование
clone()
метода → без вызова конструктора5. Использование десериализации → нет вызова конструктора
Первые три
new
ключевых слова методов и обаnewInstance()
включают вызов конструктора, но позже два метода клонирования и десериализации создают объекты без вызова конструктора.Все вышеперечисленные методы имеют разные байт-коды, связанные с ними. Прочитайте различные способы создания объектов в Java с примером для примеров и более подробным описанием, например преобразование байт-кода всех этих методов.
Однако можно утверждать, что создание массива или строкового объекта также является способом создания объекта, но эти вещи более специфичны только для некоторых классов и обрабатываются непосредственно JVM, в то время как мы можем создать объект любого класса, используя эти 5 способов.
источник
Клонирование и десериализация .
источник
Также вы можете использовать
источник
Это следует заметить, если вы новичок в Java, каждый объект унаследовал от объекта
Защищенный нативный объект clone () создает исключение CloneNotSupportedException;
источник
Также вы можете десериализовать данные в объект. Это не проходит через конструктор класса!
ОБНОВЛЕНО : Спасибо, Том, за то, что указал на это в своем комментарии! И Майкл тоже экспериментировал.
Пожалуйста, смотрите ответ Тома для полной обработки всех случаев ;-)
есть ли другой способ создания объекта без использования ключевого слова "new" в java
источник
Существует тип объекта, который не может быть создан обычными механизмами создания экземпляров (вызывающими конструкторами): массивы . Массивы создаются с
или
Как сказал Шон в комментарии, это синтаксически похоже на вызов конструктора, и внутренне это не намного больше, чем выделение и инициализация нулями (или инициализация с явным содержимым, во втором случае) блока памяти, с некоторым заголовком для обозначения тип и длина.
При передаче аргументов в varargs-метод там тоже создается (и заполняется) массив неявно.
Четвертый способ будет
Конечно, клонирование и десериализация работает и здесь.
В Стандартном API есть много методов, которые создают массивы, но все они фактически используют один (или более) из этих способов.
источник
new
ключевым словом. Array.newInstance - единственный новый механизм здесьДругие способы, если мы исчерпывающие.
anewarray
,multianewarray
,newarray
илиnew
. Они могут быть добавлены с использованием таких библиотек, как ASM или BCEL. Версия bcel поставляется с Oracle Java. Опять же, это не вызывает конструктор, но вы можете вызвать конструктор как отдельный вызов.источник
Отражение:
источник
Reflection также сделает всю работу за вас.
это еще один способ создать новый экземпляр класса. В этом случае вам также потребуется обработать исключения, которые могут быть сгенерированы.
источник
new
оператор (таким образом вызывая конструктор)clazz.newInstance()
(которое снова вызывает конструктор). Илиclazz.getConstructor(..).newInstance(..)
(снова используя конструктор, но вы можете выбрать, какой из них)Резюмировать ответ - один из основных способов - вызывая конструктор класса объекта.
Обновление: в другом ответе перечислены два способа, которые не связаны с использованием конструктора - десерализация и клонирование.
источник
Существует пять различных способов создания объектов в Java:
1. Используя ключевое слово `new`:
Это наиболее распространенный способ создания объекта в Java. Почти 99% объектов созданы таким образом.
2. Используя фабричный метод:
Пример:
3. Используя концепцию клонирования:
Используя
clone()
,clone()
можно использовать для создания копии существующего объекта.4. Используя `Class.forName ()`:
Если мы знаем имя класса & если у него есть открытый конструктор по умолчанию, мы можем создать объект таким способом.
Пример:
5. Использование десериализации объекта:
Десериализация объекта - это не что иное, как создание объекта из его сериализованной формы.
источник
Class.forName()
случае, если у вас еще нет класса, что во всех остальных случаях у вас есть. Он также не требует конструктора без аргументов: есть способы вызвать любой открытый конструктор, если вы знаете правильные аргументы. И вы оставили не менее двух других способов.Вы также можете клонировать существующий объект (если он реализует Cloneable).
источник
Способ 1
Используя новое ключевое слово. Это наиболее распространенный способ создания объекта в Java. Почти 99% объектов созданы таким образом.
Способ 2
Использование Class.forName (). Class.forName () предоставляет вам объект класса, который полезен для отражения. Методы этого объекта определяются Java, а не программистом, пишущим класс. Они одинаковы для всех классов. Вызов newInstance () для этого дает вам экземпляр этого класса (то есть, вызывающийClass.forName ("ExampleClass"). NewInstance () это эквивалентно вызову нового ExampleClass ()), в котором вы можете вызывать методы, которые определяет класс, доступ к видимым полям и т. д.
Class.forName () всегда будет использовать ClassLoader вызывающей стороны, тогда как ClassLoader.loadClass () может указывать другой ClassLoader. Я считаю, что Class.forName также инициализирует загруженный класс, тогда как подход ClassLoader.loadClass () не делает этого сразу (он не инициализируется, пока не будет использован в первый раз).
Другой должен прочитать:
Java: Введение в состояние потока с примером Простой пример перечисления Java
Способ 3
Использование clone (). С помощью clone () можно создать копию существующего объекта.
Способ 4
Использование метода newInstance ()
Способ 5
Использование десериализации объекта. Десериализация объекта - это не что иное, как создание объекта из его сериализованной формы.
источник
С точки зрения пользователя API, другой альтернативой конструкторам являются статические фабричные методы (например, BigInteger.valueOf ()), хотя для автора API (и технически «для реального») объекты все еще создаются с использованием конструктора.
источник
Зависит от того, что вы подразумеваете под созданием, но есть и другие:
источник
есть также ClassLoader.loadClass (string), но это не часто используется.
и если вы хотите быть абсолютным юристом по этому поводу, технически массивы являются объектами из-за свойства массива .length. поэтому инициализация массива создает объект.
источник
Мы можем создать объекты 5 способами:
источник
Мы также можем создать объект следующим образом:
Никто не обсуждал это.
источник