Quais são as diferentes maneiras de criar um objeto em Java?

178

Teve uma conversa com um colega de trabalho outro dia sobre isso.

Existe o óbvio usando um construtor, mas quais são as outras maneiras?

Mike Deck
fonte
2
Em caso de dúvida, observe as especificações do idioma. 12.5 Criação de novas instâncias de classe java.sun.com/docs/books/jls/third_edition/html/… 15.9 Expressões de criação de instância de classe java.sun.com/docs/books/jls/third_edition/html/…
Amigo da Internet
9
existem apenas três: c-tor normal (nova palavra-chave), clone () e Unsafe.allocateInstance(Class). O resto chama um desses. A reflexão é compilada para chamada c-tor, desserialização para Unsafe.allocateInstance (Class). Você pode criar sua própria API e acabará chamando uma delas.
bestsss 25/02
2
@ bestsss- Unsafeé um detalhe específico da implementação do Java e não é mencionado em nenhum lugar da especificação. É inteiramente possível construir uma aplicação Java compatível que não usa compilação baixo reflexão para o código que usa new, cloneou Unsafe.allocateInstance.
templatetypedef

Respostas:

288

Existem quatro maneiras diferentes de criar objetos em java:

Um . Usando a newpalavra-chave
Essa é a maneira mais comum de criar um objeto em java. Quase 99% dos objetos são criados dessa maneira.

 MyObject object = new MyObject();

B . Usando Class.forName()
Se sabemos o nome da classe e se ela possui um construtor público padrão, podemos criar um objeto dessa maneira.

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

C . Usando clone()
O clone () pode ser usado para criar uma cópia de um objeto existente.

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

D . Usar object deserialization
desserialização de objetos nada mais é do que criar um objeto a partir de sua forma serializada.

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

Você pode lê-los aqui .

kamaci
fonte
10
Então, na verdade, existem apenas 2 maneiras: chamar o construtor (usando new, clone () ou reflexão) e desserialização que não chama o construtor.
AlexR
13
@ Alex: Object.clone()não invoca construtor também.
axtavt 24/02
1
Como essa parece ser a resposta no topo, você poderia adicionar as criações de matrizes como sub-casos a A e B? (Veja minha resposta para detalhes).
Pa Elo Ebermann 25/02
A desserialização chama um construtor, mas não do tipo mais derivado.
Tom Hawtin - tackline
2
Você também deve mencionar a Constructorclasse, que generaliza Class.newInstance.
templatetypedef
68

Existem várias maneiras:

  • Através Class.newInstance.
  • Através Constructor.newInstance.
  • Através da desserialização (usa o construtor no-args da classe base não derivável mais derivada).
  • Through Object.clone( não chama um construtor ).
  • Através do JNI (deve chamar um construtor).
  • Através de qualquer outro método que chama um newpara você.
  • Eu acho que você poderia descrever o carregamento de classe como criando novos objetos (como internados String).
  • Uma matriz literal como parte da inicialização em uma declaração (sem construtor para matrizes).
  • A matriz em uma ...chamada de método "varargs" ( ) (sem construtor para matrizes).
  • Concatenação de cadeia constante de tempo não compilado (produz pelo menos quatro objetos, em uma implementação típica).
  • Fazendo com que uma exceção seja criada e lançada pelo tempo de execução. Por exemplo throw null;ou "".toCharArray()[0].
  • Ah, e boxe de primitivos (a menos que sejam armazenados em cache), é claro.
  • O JDK8 deve ter lambdas (classes internas anônimas essencialmente concisas), que são implicitamente convertidas em objetos.
  • Para completar (e Pa andlo Ebermann), também há alguma sintaxe com a newpalavra - chave.
Tom Hawtin - linha de orientação
fonte
6
Você deve adicionar o "modo normal", também :-)
Paulo Ebermann
@ Paolo Ebermann Isso é tão antiquado e não é legal. (Presumi que o que a pergunta quis dizer com "use um construtor (embora a maioria, mas não todas, as opções acima use o construtor / algures ao longo da linha).)"
Tom Hawtin - tackline
Na verdade, existem apenas 3 maneiras reais para fazê-lo, para que eu adicionei comentário
bestsss
3
Você perdeu um: java.misc.Unsafe.allocateInstance(). Embora isso seja desagradável por várias razões. E, na verdade, a desserialização não usa o construtor no-args. Sob o capô, ele usa allocateInstanceou magia negra equivalente.
Stephen C
Melhor resposta ainda, mas o JNI AllocObject().não chama um construtor.
Marquês de Lorne
25

Na linguagem Java, a única maneira de criar um objeto é chamando seu construtor, seja explícita ou implicitamente. Usando resultados de reflexão em uma chamada para o método construtor, a desserialização usa reflexão para chamar o construtor, os métodos de fábrica envolvem a chamada ao construtor para abstrair a construção real e a clonagem é similarmente uma chamada de construtor encapsulada.

Confusão
fonte
1
Incorreta. Deserializatio não chama o construtor de uma classe, explícita ou implicitamente.
Marquês de Lorne
2
Eu não deveria ter escrito 'seu construtor' e 'o construtor', mas 'um construtor' e 'um construtor'. No caso de desserialização, o primeiro construtor no-arg aplicável é sempre chamado.
Confusion
1
A implementação do clone padrão não chama nenhum construtor.
Didier L
se esta é a minha implementação do método clone "return super.clone ();". Então, ele não chamará o construtor.
Mateen 26/05
13

Sim, você pode criar objetos usando reflexão. Por exemplo, String.class.newInstance()você fornecerá um novo objeto String vazio.

Thomas Lötzer
fonte
1
Se eu usar isso, está me pedindo para incluir um bloco try / catch.
precisa saber é o seguinte
2
Sim, existem muitos casos em que exceções podem ser lançadas. Veja o JavaDoc para newInstance () para exemplos do que pode dar errado.
Thomas Lötzer
11

Existem cinco maneiras diferentes de criar um objeto em Java,

1. Usando a newpalavra-chave → construtor é chamado

Employee emp1 = new Employee();

2. Usando o newInstance()método deClass → construtor é chamado

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

Também pode ser escrito como

Employee emp2 = Employee.class.newInstance();

3. Usando o newInstance()método deConstructor → construtor é chamado

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

4. Usando o clone()método → nenhuma chamada de construtor

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

5. Usando desserialização → nenhuma chamada de construtor

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

Os três primeiros métodos de newpalavra-chave e ambos newInstance()incluem uma chamada de construtor, mas mais tarde dois métodos de clone e desserialização criam objetos sem chamar o construtor.

Todos os métodos acima têm bytecode diferente associado a eles, Leia Diferentes maneiras de criar objetos em Java com Exemplo para exemplos e descrição mais detalhada, por exemplo, conversão de bytecode de todos esses métodos.

No entanto, pode-se argumentar que a criação de um objeto de matriz ou string também é uma maneira de criar o objeto, mas essas coisas são mais específicas apenas para algumas classes e tratadas diretamente pela JVM, enquanto podemos criar um objeto de qualquer classe usando essas 5 maneiras.

Naresh Joshi
fonte
Divulgue quaisquer afiliações e não use o site como forma de promover seu site através da publicação. Consulte Como escrevo uma boa resposta? .
Yvette - Restabelece Monica
6

Você também pode usar

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

Isso deve ser notado se você é novo no java, todo objeto herdou de Object

Objeto nativo protegido clone () lança CloneNotSupportedException;

empilhador
fonte
@stacker: Você poderia explicar como isso está relacionado à criação de um novo objeto? Obrigado.
Ryanprayogo 20/01/10
4
@ryanprayogo clone () retornará um novo objeto (mesmo que o objeto seja um clone do objeto em que clone () foi chamado) e é realmente a única maneira de criar um novo objeto sem que o construtor seja chamado.
Thomas Lötzer
6

Além disso, você pode desserializar dados em um objeto. Isso não passa pela classe Constructor!


ATUALIZADO : Obrigado Tom por apontar isso no seu comentário! E Michael também experimentou.

Ele passa pelo construtor da superclasse não-serializável mais derivada.
E quando essa classe não tem construtor no-args, uma InvalidClassException é lançada na desserialização.

Por favor, veja a resposta de Tom para um tratamento completo de todos os casos ;-)
Existe alguma outra maneira de criar um objeto sem usar a palavra-chave "new" em java

KLE
fonte
1
Ele passa por um construtor (o construtor não-arg da superclasse não derivável mais derivada).
Tom Hawtin - defina
1
@ Tom Oh uau - eu não sabia disso e experimentei um pouco. Aparentemente, quando a superclasse não serializável mais derivada não possui um construtor no-args, isso resulta em uma InvalidClassException sendo serializada no fluxo e lançada após a desserialização !! - Quão bizarro é isso?
Michael Borgwardt
6

Existe um tipo de objeto que não pode ser construído por mecanismos normais de criação de instância (chamando construtores): Arrays . Matrizes são criadas com

 A[] array = new A[len];

ou

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

Como Sean disse em um comentário, isso é sintaticamente semelhante a uma chamada de construtor e, internamente, não é muito mais que alocação e inicialização zero (ou inicialização com conteúdo explícito, no segundo caso) um bloco de memória, com algum cabeçalho para indicar o tipo e comprimento.

Ao passar argumentos para um método varargs, uma matriz também é criada (e preenchida) implicitamente.

Uma quarta maneira seria

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

Obviamente, a clonagem e a desserialização também funcionam aqui.

Existem muitos métodos na API padrão que criam matrizes, mas todos eles estão de fato usando uma (ou mais) dessas maneiras.

Paŭlo Ebermann
fonte
Concedido, você não pode definir construtores Array, mas, além disso, o mecanismo é a mesma newpalavra-chave. Array.newInstance é o único mecanismo novo aqui #
Sean Patrick Floyd
@ Sean: É a mesma palavra-chave, mas é um mecanismo interno bem diferente, ouso dizer.
Pa Elo Ebermann 4/12/12
Isso é verdade, é claro. Mas, por outro lado, as diferentes versões da criação de matrizes são internamente praticamente as mesmas. Só percebi a sua resposta foi a partir de 2011. Desculpe para agitar-se coisas velhas :-)
Sean Patrick Floyd
@ Sean: Não tem problema, eu usei esta ocasião para fazer algumas correções gramaticais.
Paŭlo Ebermann 4/12/12
bom trabalho, ninguém discutiu aqui sobre matrizes!
Mateen 26/05
5

Outras maneiras, se estamos sendo exaustivos.

  • No Oracle, a JVM é Unsafe.allocateInstance (), que cria uma instância sem chamar um construtor.
  • Usando a manipulação de código byte você pode adicionar código para anewarray, multianewarray, newarrayou new. Eles podem ser adicionados usando bibliotecas como ASM ou BCEL. Uma versão do bcel é fornecida com o Java da Oracle. Novamente, isso não chama um construtor, mas você pode chamar um construtor como uma chamada separada.
Peter Lawrey
fonte
4

Reflexão:

someClass.newInstance();
John Meagher
fonte
4

O Reflection também fará o trabalho para você.

SomeClass anObj = SomeClass.class.newInstance();

é outra maneira de criar uma nova instância de uma classe. Nesse caso, você também precisará lidar com as exceções que podem ser lançadas.

ryanprayogo
fonte
4
  • usando o newoperador (chamando assim um construtor)
  • usando reflexão clazz.newInstance()(que novamente chama o construtor). Ou por clazz.getConstructor(..).newInstance(..)(novamente usando um construtor, mas você pode escolher qual)

Para resumir a resposta - uma maneira principal - invocando o construtor da classe do objeto.

Atualização: Outra resposta listou duas maneiras que não envolvem o uso de um construtor - desseralização e clonagem.

Bozho
fonte
4

Existem CINCO maneiras diferentes de criar objetos em Java:

1. Usando a palavra-chave `new`:

Essa é a maneira mais comum de criar um objeto em Java. Quase 99% dos objetos são criados dessa maneira.

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

2. Usando o Método de Fábrica:

ClassName ObgRef=ClassName.FactoryMethod();

Exemplo:

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

3. Usando o conceito de clonagem:

Ao usar clone(), o clone()pode ser usado para criar uma cópia de um objeto existente.

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

4. Usando `Class.forName ()`:

Se soubermos o nome da classe e se tiver um construtor público padrão, podemos criar um objeto dessa maneira.

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

Exemplo:

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

5. Usando desserialização de objeto:

A desserialização de objetos nada mais é do que criar um objeto a partir de sua forma serializada.

ObjectInputStreamName inStream = new ObjectInputStreamName(anInputStream );
MyObjectName object = (MyObjectNmae) inStream.readObject();
KVSubrahmanya Reddy
fonte
(4) requer apenas Class.forName()se você ainda não tem a classe, o que em todos os outros casos você tem. Também não requer um construtor no-args: existem maneiras de chamar qualquer construtor público se você souber os argumentos corretos. E você deixou de fora pelo menos duas outras maneiras.
Marquês de Lorne
2
(2) O Método de Fábrica é apenas um padrão para obter objetos. Mas internamente, ele usa "nova" palavra-chave para criar objetos.
Karthik Bose
cara, por que tantas pessoas dizem que o método de fábrica cria objetos, de onde vocês aprenderam isso?
Mateen 26/05
3

Você também pode clonar objetos existentes (se implementar Cloneable).

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

Método 1

Usando nova palavra-chave. Essa é a maneira mais comum de criar um objeto em java. Quase 99% dos objetos são criados dessa maneira.

Employee object = new Employee();

Método 2

Usando Class.forName (). Class.forName () fornece o objeto de classe, que é útil para reflexão. Os métodos que esse objeto possui são definidos por Java, não pelo programador que está escrevendo a classe. Eles são os mesmos para todas as classes. A chamada newInstance () fornece uma instância dessa classe (ou seja, chamandoClass.forName ("ExampleClass"). NewInstance () é equivalente a chamar new ExampleClass ()), na qual você pode chamar os métodos que a classe define, acesse os campos visíveis etc.

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

Class.forName () sempre usará o ClassLoader do chamador, enquanto ClassLoader.loadClass () pode especificar um ClassLoader diferente. Acredito que Class.forName inicialize a classe carregada também, enquanto a abordagem ClassLoader.loadClass () não faz isso imediatamente (não é inicializada até que seja usada pela primeira vez).

Outro deve ler:

Java: Introdução ao estado do encadeamento com exemplo Exemplo simples de Java Enum

Método 3

Usando clone (). O clone () pode ser usado para criar uma cópia de um objeto existente.

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

Método 4

Usando o método newInstance ()

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

Método 5

Usando desserialização de objetos. A desserialização de objetos nada mais é do que criar um objeto a partir de sua 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
fonte
Não use formatação de código para texto que não seja código. Existem mais métodos que estes. Leia as outras respostas. 'Quase 99%' é apenas adivinhação.
Marquês de Lorne
Oi EJP muito por este erro ... Eu disse que isso é um tipo de forma de criar os objetos não disse exatamente seus os one.Its direito apenas um model..and pena alearner am e novo para stackoverflow
Andriya
0

Da perspectiva do usuário da API, outra alternativa aos construtores são os métodos estáticos de fábrica (como BigInteger.valueOf ()), embora para o autor da API (e tecnicamente "de verdade") os objetos ainda sejam criados usando um construtor.

Fabian Steeg
fonte
-1

Depende exatamente do que você quer dizer com criar, mas outros são:

  • Método de clone
  • Desserialização
  • Reflexão (Class.newInstance ())
  • Reflexão (objeto Construtor)
Garth Gilmour
fonte
2
3 e 4 são aliases diferentes para o mesmo mecanismo #
Sean Patrick Floyd
-2

também há ClassLoader.loadClass (string), mas isso geralmente não é usado.

e se você quiser ser um advogado total, matrizes são tecnicamente objetos por causa da propriedade .length de uma matriz. portanto, inicializar uma matriz cria um objeto.

Randy L
fonte
1
loadClass (String name) retorna o objeto Class resultante, que é um objeto yes Mas não o objeto dessa classe. Se exemplos são dados, podemos encontrar vários exemplos em toda a biblioteca java, mas esses serão específicos da classe. Verifique youtu.be/gGGCmrD6Qpw
nanosoft
-3

Podemos criar um objeto de 5 maneiras:

  1. pelo novo operador
  2. por reflexão (por exemplo, Class.forName () seguido por Class.newInstance ())
  3. pelo método de fábrica
  4. por clonagem
  5. pela reflexão api
tanushree roy
fonte
3
Class.forName () carrega uma classe em vez de criar um objeto.
Marquês de Lorne
reflexão? Certamente você quer dizer reflexão.
Stephen C
como você criaria um objeto a partir do método de fábrica, a implementação interna pode estar novamente usando a nova palavra-chave, certo? e por que você reflete duas vezes? Faria mais sentido se você realmente desse alguns exemplos.
Mateen
-5

Também podemos criar o objeto desta maneira: -

String s ="Hello";

Ninguém discutiu isso.

Deepak Sharma
fonte
Essa é a maneira de criar tipos de dados primitivos, é apenas uma flexibilidade que o Java fornece nos bastidores para não usar a palavra-chave "nova". É a mesma que a nova palavra-chave.
Madusudanan
Madhusudan, FYI, Com a ajuda de um novo operador, os objetos devem sempre ser armazenados na pilha, enquanto neste caso "Hello" é um objeto que deve ser armazenado no pool de String. E String é uma classe e não um tipo de dados primitivo.
precisa
Isso não cria um objeto. Ele atribui uma referência a um objeto existente. O objeto já havia sido criado pelo compilador e pelo carregador de classe.
Marquês de Lorne