¿Cuáles son las diferentes formas de crear un objeto en Java?

178

Tuve una conversación con un compañero de trabajo el otro día sobre esto.

Lo obvio es usar un constructor, pero ¿cuáles son las otras formas allí?

Mike Deck
fuente
2
En caso de duda, consulte las especificaciones del idioma. 12.5 Creación de nuevas instancias de clase java.sun.com/docs/books/jls/third_edition/html/… 15.9 Expresiones de creación de instancia de clase java.sun.com/docs/books/jls/third_edition/html/…
Internet Friend
9
solo hay 3: c-tor normal (nueva palabra clave), clone () y Unsafe.allocateInstance(Class). El resto llama a uno de esos. La reflexión se compila para llamar a c-tor, deserialización a Unsafe.allocateInstance (Class). Puede crear su propia API y terminará llamando a una de ellas.
bestsss
2
@ bestsss- Unsafees un detalle específico de implementación de Java y no se menciona en ninguna parte de la especificación. Es perfectamente posible construir una aplicación Java compatible que no utiliza la reflexión abajo compilación de código que utiliza new, cloneo Unsafe.allocateInstance.
templatetypedef

Respuestas:

288

Hay cuatro formas diferentes de crear objetos en Java:

Una . Uso de la newpalabra clave
Esta es la forma más común de crear un objeto en Java. Casi el 99% de los objetos se crean de esta manera.

 MyObject object = new MyObject();

B . Uso Class.forName()
Si conocemos el nombre de la clase y si tiene un constructor público predeterminado, podemos crear un objeto de esta manera.

MyObject object = (MyObject) Class.forName("subin.rnd.MyObject").newInstance();

C . Uso clone()
El clon () se puede usar para crear una copia de un objeto existente.

MyObject anotherObject = new MyObject();
MyObject object = (MyObject) anotherObject.clone();

D . Usar la object deserialization
deserialización de objetos no es más que crear un objeto a partir de su forma serializada.

ObjectInputStream inStream = new ObjectInputStream(anInputStream );
MyObject object = (MyObject) inStream.readObject();

Puedes leerlos desde aquí .

kamaci
fuente
10
Entonces, en realidad, solo existen 2 formas: llamar al constructor (usando new, clone () o reflexión) y deserialización que no invoca al constructor.
AlexR
13
@AlexR: Object.clone()no invoca al constructor también.
axtavt
1
Como esta parece ser la respuesta en la parte superior, ¿podría agregar las creaciones de matrices como sub-casos a A y B? (Ver mi respuesta para más detalles).
Paŭlo Ebermann
La deserialización invoca a un constructor, pero no del tipo más derivado.
Tom Hawtin - tackline
2
También debe mencionar la Constructorclase, que generaliza Class.newInstance.
templatetypedef
68

Hay varias formas:

  • A través de Class.newInstance.
  • A través de Constructor.newInstance.
  • A través de la deserialización (usa el constructor sin argumentos de la clase base no derivable más serializable).
  • Through Object.clone( no llama a un constructor ).
  • A través de JNI (debería llamar a un constructor).
  • A través de cualquier otro método que llame newpor usted.
  • Supongo que podría describir la carga de clases como la creación de nuevos objetos (como Strings internos ).
  • Una matriz literal como parte de la inicialización en una declaración (sin constructor para matrices).
  • La matriz en una ...llamada al método "varargs" ( ) (sin constructor para matrices).
  • Concatenación de cadenas constante de tiempo sin compilación (produce al menos cuatro objetos, en una implementación típica).
  • Causar una excepción para ser creada y lanzada por el tiempo de ejecución. Por ejemplo throw null;o "".toCharArray()[0].
  • Ah, y el boxeo de primitivas (a menos que estén en caché), por supuesto.
  • JDK8 debería tener lambdas (clases internas anónimas esencialmente concisas), que se convierten implícitamente en objetos.
  • Para completar (y Paŭlo Ebermann), también hay alguna sintaxis con la newpalabra clave.
Tom Hawtin - tackline
fuente
66
También debe agregar la "forma normal" :-)
Paŭlo Ebermann
@ Paŭlo Ebermann Eso es tan anticuado y anticuado. (Supuse que lo que la pregunta entiende por "utilizar un constructor (aunque la mayoría, pero no todos, de lo anterior hace uso de la / a en alguna parte a lo largo de la línea del constructor).)
Tom Hawtin - tackline
En realidad, hay sólo 3 maneras reales para hacerlo, por lo que añadí comentario
bestsss
3
Se ha perdido uno: java.misc.Unsafe.allocateInstance(). Aunque eso es desagradable por varias razones. Y en realidad, la deserialización no usa el constructor sin argumentos. Debajo del capó se usa allocateInstanceo magia negra equivalente.
Stephen C
La mejor respuesta aún, pero JNI AllocObject().no llama a un constructor.
Marqués de Lorne
25

Dentro del lenguaje Java, la única forma de crear un objeto es llamando a su constructor, ya sea explícita o implícitamente. Usando los resultados de la reflexión en una llamada al método del constructor, la deserialización usa la reflexión para llamar al constructor, los métodos de fábrica envuelven la llamada al constructor para abstraer la construcción real y la clonación es, de manera similar, una llamada del constructor envuelto.

Confusión
fuente
1
Incorrecto. Deserializatio no llama al constructor de una clase ni explícita ni implícitamente.
Marqués de Lorne
2
No debería haber escrito 'su constructor' y 'el constructor', sino más bien 'un constructor' y 'un constructor'. En el caso de la deserialización, siempre se llama al primer constructor sin argumentos aplicable.
Confusión
1
La implementación de clonación predeterminada no llama a ningún constructor.
Didier L
si esta es mi implementación del método de clonación "return super.clone ();". Entonces no invocará al constructor.
Mateen
13

Sí, puedes crear objetos usando la reflexión. Por ejemplo, String.class.newInstance()le dará un nuevo objeto String vacío.

Thomas Lötzer
fuente
1
si uso esto, me está pidiendo que lo incluya en un bloque try / catch.
GuruKulki
2
Sí, hay muchos casos en los que se pueden lanzar excepciones. Consulte JavaDoc para newInstance () para ver ejemplos de lo que podría salir mal.
Thomas Lötzer
11

Hay cinco formas diferentes de crear un objeto en Java,

1. Usando la newpalabra clave → constructor llamarse

Employee emp1 = new Employee();

2. Usando el newInstance()método deClass → constructor llamarse

Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee")
                                .newInstance();

También se puede escribir como

Employee emp2 = Employee.class.newInstance();

3. Usando el newInstance()método deConstructor → constructor llamarse

Constructor<Employee> constructor = Employee.class.getConstructor();
Employee emp3 = constructor.newInstance();

4. Usando el clone()método → sin llamada de constructor

Employee emp4 = (Employee) emp3.clone();

5. Uso de deserialización → sin llamada de constructor

ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
Employee emp5 = (Employee) in.readObject();

Los primeros tres métodos de newpalabras clave y ambos newInstance()incluyen una llamada al constructor, pero luego dos métodos de clonación y deserialización crean objetos sin llamar al constructor.

Todos los métodos anteriores tienen diferentes códigos de bytes asociados con ellos, Leer Diferentes formas de crear objetos en Java con ejemplos para ejemplos y descripciones más detalladas, por ejemplo, conversión de códigos de bytes de todos estos métodos.

Sin embargo, se puede argumentar que crear una matriz o un objeto de cadena también es una forma de crear el objeto, pero estas cosas son más específicas solo para algunas clases y son manejadas directamente por JVM, mientras que podemos crear un objeto de cualquier clase usando estas 5 formas.

Naresh Joshi
fuente
Revele cualquier afiliación y no use el sitio como una forma de promocionar su sitio a través de la publicación. Vea ¿Cómo escribo una buena respuesta? .
Yvette
6

También puedes usar

 Object myObj = Class.forName("your.cClass").newInstance();
Vincent Ramdhanie
fuente
6

Esto debe tenerse en cuenta si eres nuevo en Java, cada objeto ha heredado de Object

Objeto nativo protegido clone () arroja CloneNotSupportedException;

apilador
fuente
@stacker: ¿Podría explicar cómo se relaciona esto con la creación de un nuevo objeto? Gracias.
ryanprayogo
44
@ryanprayogo clone () devolverá un nuevo objeto (a pesar de que el objeto es un clon del objeto al que se llamó clone ()) y es en realidad la única forma de crear un nuevo objeto sin que se llame al constructor.
Thomas Lötzer
6

Además, puede des-serializar datos en un objeto. ¡Esto no pasa por la clase Constructor!


ACTUALIZADO : ¡Gracias Tom por señalar eso en tu comentario! Y Michael también experimentó.

Pasa por el constructor de la superclase no serializable más derivada.
Y cuando esa clase no tiene un constructor sin argumentos, se produce una InvalidClassException al deserializar.

Vea la respuesta de Tom para un tratamiento completo de todos los casos ;-)
¿Hay alguna otra forma de crear un objeto sin usar la palabra clave "nuevo" en Java

KLE
fuente
1
Sí pasa por un constructor (el constructor sin argumentos de la superclase no serializable más derivada).
Tom Hawtin - tackline
1
@Tom Oh wow: no lo sabía y experimenté un poco. ¡Aparentemente, cuando la superclase no serializable más derivada no tiene un constructor sin argumentos, resulta en una InvalidClassException serializada en la secuencia y lanzada tras la deserialización! - ¿Qué extraño es eso?
Michael Borgwardt
6

Hay un tipo de objeto que no puede construirse mediante mecanismos normales de creación de instancias (llamados constructores): matrices . Las matrices se crean con

 A[] array = new A[len];

o

 A[] array = new A[] { value0, value1, value2 };

Como dijo Sean en un comentario, esto es sintácticamente similar a una llamada de constructor e internamente no es mucho más que asignación e inicialización cero (o inicialización con contenido explícito, en el segundo caso) un bloque de memoria, con algún encabezado para indicar el tipo y la longitud.

Al pasar argumentos a un método varargs, también se crea una matriz (y se llena) implícitamente.

Una cuarta forma sería

 A[] array = (A[]) Array.newInstance(A.class, len);

Por supuesto, la clonación y la deserialización también funcionan aquí.

Hay muchos métodos en la API estándar que crean matrices, pero todos de hecho están utilizando una (o más) de estas formas.

Paŭlo Ebermann
fuente
Por supuesto, no puede definir constructores de matrices, pero aparte de eso, el mecanismo es la misma newpalabra clave. Array.newInstance es el único mecanismo nuevo aquí
Sean Patrick Floyd el
@Sean: es la misma palabra clave, pero es un mecanismo interno bastante diferente, me atrevo a decir.
Paŭlo Ebermann
Eso es cierto, por supuesto. Pero, por otro lado, las diferentes versiones de la creación de matrices son internamente más o menos las mismas. Acabo de darme cuenta de que su respuesta era de 2011. Perdón por agitar cosas viejas :-)
Sean Patrick Floyd
@Sean: No hay problema, aproveché esta ocasión para hacer una corrección gramatical.
Paŭlo Ebermann
buen trabajo, nadie discutió aquí sobre arreglos!
Mateen
5

Otras formas si estamos siendo exhaustivos.

  • En Oracle JVM está Unsafe.allocateInstance () que crea una instancia sin llamar a un constructor.
  • Usando la manipulación de código de byte puede agregar código a anewarray , multianewarray, newarrayo new. Estos se pueden agregar utilizando bibliotecas como ASM o BCEL. Se envía una versión de bcel con Java de Oracle. De nuevo, esto no llama a un constructor, pero puede llamar a un constructor como una llamada separada.
Peter Lawrey
fuente
4

Reflexión:

someClass.newInstance();
John Meagher
fuente
4

La reflexión también hará el trabajo por ti.

SomeClass anObj = SomeClass.class.newInstance();

Es otra forma de crear una nueva instancia de una clase. En este caso, también tendrá que manejar las excepciones que se pueden generar.

ryanprayogo
fuente
4
  • utilizando la new operador (invocando un constructor)
  • usando la reflexión clazz.newInstance()(que nuevamente invoca al constructor). O bien clazz.getConstructor(..).newInstance(..)(de nuevo utilizando un constructor, pero puede elegir cuál)

Para resumir la respuesta, una forma principal, invocando al constructor de la clase del objeto.

Actualización: Otra respuesta enumeró dos formas que no implican el uso de un constructor: deseralización y clonación.

Bozho
fuente
4

Hay CINCO formas diferentes de crear objetos en Java:

1. Usando la palabra clave `new`:

Esta es la forma más común de crear un objeto en Java. Casi el 99% de los objetos se crean de esta manera.

MyObject object = new MyObject();//normal way

2. Mediante el uso del método de fábrica:

ClassName ObgRef=ClassName.FactoryMethod();

Ejemplo:

RunTime rt=Runtime.getRunTime();//Static Factory Method

3. Mediante el uso del concepto de clonación:

Al usar clone(), clone()se puede usar para crear una copia de un objeto existente.

MyObjectName anotherObject = new MyObjectName();
MyObjectName object = anotherObjectName.clone();//cloning Object

4. Usando `Class.forName ()`:

Si conocemos el nombre de la clase y si tiene un constructor público predeterminado, podemos crear un objeto de esta manera.

MyObjectName object = (MyObjectNmae) Class.forName("PackageName.ClassName").newInstance();

Ejemplo:

String st=(String)Class.forName("java.lang.String").newInstance();

5. Usando la deserialización de objetos:

La deserialización de objetos no es más que crear un objeto a partir de su forma serializada.

ObjectInputStreamName inStream = new ObjectInputStreamName(anInputStream );
MyObjectName object = (MyObjectNmae) inStream.readObject();
KVSubrahmanya Reddy
fuente
(4) solo se requiere Class.forName()si aún no tiene la clase, que en todos los demás casos sí la tiene. Tampoco requiere un constructor sin argumentos: hay formas de llamar a cualquier constructor público si conoce los argumentos correctos. Y has omitido al menos otras dos formas.
Marqués de Lorne
2
(2) El Método de fábrica es solo un patrón para obtener objetos. Pero internamente utiliza la palabra clave "nueva" para crear objetos.
Karthik Bose
¿Por qué tanta gente dice que el método de fábrica crea objetos, de dónde aprendieron esto?
Mateen
3

También puede clonar un objeto existente (si implementa Cloneable).

Foo fooClone = fooOriginal.clone (); 
romano
fuente
2

Método 1

Usando nueva palabra clave. Esta es la forma más común de crear un objeto en Java. Casi el 99% de los objetos se crean de esta manera.

Employee object = new Employee();

Método 2

Usando Class.forName (). Class.forName () le proporciona el objeto de clase, que es útil para la reflexión. Los métodos que tiene este objeto los define Java, no el programador que escribe la clase. Son iguales para todas las clases. Llamar a newInstance () en eso le da una instancia de esa clase (es decir, callingClass.forName ("ExampleClass"). NewInstance () es equivalente a llamar a new ExampleClass ()), en el que puede llamar a los métodos que la clase define, acceder a los campos visibles, etc.

Employee object2 = (Employee) Class.forName(NewEmployee).newInstance();

Class.forName () siempre usará el ClassLoader de la persona que llama, mientras que ClassLoader.loadClass () puede especificar un ClassLoader diferente. Creo que Class.forName también inicializa la clase cargada, mientras que el enfoque ClassLoader.loadClass () no lo hace de inmediato (no se inicializa hasta que se usa por primera vez).

Otro debe leer:

Java: Introducción de estado de subproceso con ejemplo Ejemplo simple de Java Enum

Método 3

Usando clon (). El clon () se puede usar para crear una copia de un objeto existente.

Employee secondObject = new Employee();
Employee object3 = (Employee) secondObject.clone();

Método 4

Usando el método newInstance ()

Object object4 = Employee.class.getClassLoader().loadClass(NewEmployee).newInstance();

Método 5

Uso de la deserialización de objetos. La deserialización de objetos no es más que crear un objeto a partir de su forma serializada.

// Create Object5
// create a new file with an ObjectOutputStream
FileOutputStream out = new FileOutputStream("");
ObjectOutputStream oout = new ObjectOutputStream(out);

// write something in the file
oout.writeObject(object3);
oout.flush();

// create an ObjectInputStream for the file we created before
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("crunchify.txt"));
Employee object5 = (Employee) ois.readObject();
Andriya
fuente
No use el formato de código para texto que no sea código. Hay más métodos que estos. Lee las otras respuestas. 'Casi el 99%' es solo una conjetura.
Marqués de Lorne
Hola EJP, perdón por este error ... Dije que este es un tipo de forma de crear los objetos que no se dice que es exactamente el correcto. Es solo un modelo ... y lo siento, soy un ganador y nuevo para
apilar overflow
0

Desde la perspectiva del usuario de la API, otra alternativa a los constructores son los métodos estáticos de fábrica (como BigInteger.valueOf ()), aunque para el autor de la API (y técnicamente "de verdad") los objetos todavía se crean utilizando un constructor.

Fabian Steeg
fuente
-1

Depende exactamente de lo que quieres decir con crear, pero algunos otros son:

  • Método de clonación
  • Deserialización
  • Reflexión (Class.newInstance ())
  • Reflexión (objeto constructor)
Garth Gilmour
fuente
2
3 y 4 son diferentes alias para el mismo mecanismo
Sean Patrick Floyd
-2

también hay ClassLoader.loadClass (string) pero esto no se usa con frecuencia.

y si desea ser un abogado total al respecto, las matrices son técnicamente objetos debido a la propiedad .length de una matriz. así que inicializar una matriz crea un objeto.

Randy L
fuente
1
loadClass (nombre de cadena) devuelve el objeto de clase resultante, que es un objeto sí, pero no el objeto de esa clase. Si se dan ejemplos, entonces podemos encontrar numerosos ejemplos de este tipo en toda la biblioteca de Java, pero serán específicos de la clase. revisa youtu.be/gGGCmrD6Qpw
nanosoft
-3

Podemos crear objetos de 5 maneras:

  1. por nuevo operador
  2. por reflexión (por ejemplo, Class.forName () seguido de Class.newInstance ())
  3. por el método de fábrica
  4. por clonación
  5. por reflexión api
tanushree roy
fuente
3
Class.forName () carga una clase en lugar de crear un objeto.
Marqués de Lorne
¿reflexión? Seguramente te refieres a la reflexión.
Stephen C
¿Cómo crearía un objeto a partir del método de fábrica? La implementación interna puede ser nuevamente usando una nueva palabra clave, ¿verdad? ¿Y por qué tienes reflejo dos veces? Tendría más sentido si realmente das algunos ejemplos
Mateen
-5

También podemos crear el objeto de esta manera: -

String s ="Hello";

Nadie lo ha discutido.

Deepak Sharma
fuente
Esta es la forma de crear tipos de datos primitivos, es solo una flexibilidad que Java proporciona detrás de escena para no usar la palabra clave "nueva". Esto es lo mismo que la palabra clave nueva.
Madusudanan
Madhusudan, para su información, con la ayuda de un nuevo operador, los objetos siempre deben almacenarse en el montón, mientras que en este caso "Hello" es un objeto que debe almacenarse en el conjunto de cadenas. Y String es una clase, no un tipo de datos primitivo.
Deepak Sharma
Esto no crea un objeto. Asigna una referencia a un objeto existente. El objeto ya había sido creado por el compilador y el cargador de clases.
Marqués de Lorne