2009-07-02 22 views
5

¿Hay alguna manera en Java que una declaración comoEn Java, ¿lo nuevo siempre es nuevo?

Thing thing = new Thing(); 

podría no resultado en un nuevo objeto que está siendo creado (es decir de ninguna manera que thing podría terminar apuntando a un objeto ya existente)?

+2

¿Por qué lo preguntas? ¿Estás obteniendo un comportamiento extraño en alguna parte? –

+2

Sin comportamiento extraño. Simplemente curioso: estaba leyendo sobre el constructor Integer (int i). El punto que se planteó fue que el método estático Integer.valueOf (int i) podría ser mejor, ya que reutilizará los objetos según sea necesario. Quería comprobar que era imposible. , no solo no convencional, para que un constructor haga lo de reutilización. –

+8

Sí, es imposible. En C++, puede anular el operador 'new', pero no puede hacerlo en Java. Lo cual no me pone triste. –

Respuesta

16

El operador new asigna un nuevo espacio dinámico y llama al constructor. Siempre obtendrá un objeto nuevo de esa manera (a menos que, como otros señalaron, se genere una excepción en el constructor).

La cosa es un poco diferente con los métodos estáticos que devuelven una referencia, como Integer.valueOf() que reutiliza los objetos de un grupo interno si es posible.

+1

Sí, e incluso es un patrón recomendado en el gran "Effective Java" de Joshua Bloch –

6

Si el constructor de Thing arroja una excepción, el objeto no se crea. Sin embargo, thing nunca apuntará a otra instancia existente de Cosa.

+0

ni en valores 'null'. Es extraño ver código como 'Thing t = new Thing(); if (t == null) ... '- nunca sucederá –

0

No, en el caso de que no haya espacio en la memoria para ello, debería obtener un OutOfMemoryError.

Por supuesto, podría haber otras excepciones lanzadas por el constructor Thing.

+0

hmmm, ¿por qué no es un OutOfMemoryError? Solo interesado. –

+0

la excepción correcta es realmente OutOfMemoryError. – cd1

+0

@ CD1 @Tim Corregido el error. Yo sabía que era algo por el estilo. my bad –

0

No estoy seguro si entiendo su pregunta correctamente. La definición de nuevo es para asignar e inicializar un nuevo objeto.

Supongo que es posible que pueda almacenar una referencia estática a un objeto, y luego clonarlo para crear un nuevo objeto, pero ese objeto aún sería nuevo.

Dado que no puede modificar el valor de this (de lo contrario, podría decir algo como this = oldObject en su constructor), la única forma en que podría hacer esto sería lanzar una excepción, como se ha mencionado anteriormente.

0

por lo que sé que no es como C++, donde puede sobrecargar operator new o hacer colocaciones nuevas u otras cosas del asignador. (pero no estoy familiarizado con el JLS)

3

El uso de new siempre dará como resultado la asignación y creación de un nuevo objeto. Sin embargo, es posible que se esté refiriendo al concepto de interna, donde los objetos se almacenan en un grupo y se pueden reutilizar para ahorrar espacio. Para ver un buen ejemplo, consulte este artículo en String interning en Java.

1

Nuevo siempre es nuevo (quizás con algunas excepciones para envoltorios primitivos), pero si reutilizar objetos es un comportamiento deseado, hay formas de hacerlo a través de ciertos patrones de diseño (singleton, fábrica, grupo, etc.).

+1

Las envolturas primitivas (también llamadas primitivas en caja) siguen las mismas reglas que cualquier otra clase: si usas un constructor para crear una, siempre obtienes una nueva instancia. Sin embargo, el autoboxing no necesariamente crea un objeto único cada vez porque usa un método de fábrica en lugar de un constructor. –

+0

¿He dicho algo diferente? – quosoo

+1

Nuevo siempre es nuevo. No hay excepciones, incluso para envoltorios primitivos. – dave4420

-1

En Java, lo único que se me ocurre es usar el patrón de Singleton. Esto no crearía múltiples instancias nuevas de Thing, sino más bien una instancia del mismo objeto cada vez.

+1

Cada vez que usa 'new', está creando una nueva instancia. Período. Con el patrón Singleton, está llamando 'SingletonClass.getInstance()', no 'new SingleClass()'. –

4

Varias personas dicen que un objeto no se creará si el constructor lanza una excepción. Solo me gustaría señalar que esto no es verdad.A modo de ejemplo, echar un vistazo a esta muy mal código:

public class Test { 
    static int count; 

    static Set<Test> set = new HashSet<Test>(); 

    int id = count++; 


    public Test() { 
     set.add(this); 
     throw new RuntimeException(); 
    } 


    public static void main(String[] args) throws Exception { 
     for(int i = 0; i < 5; i++) { 
      try { 
       new Test(); 
      } catch(Exception e) { 
      } 
     } 
     System.out.println(set); 
    } 


    public String toString() { 
     return "Test[" + id + "]"; 
    } 
} 

La salida es:

[Test[0], Test[1], Test[2], Test[4], Test[3]] 

new crea un nuevo objeto cada vez.

0

nuevo siempre crea un objeto nuevo. En java no puedes reutilizar objetos usando new. Realmente esto lleva al problema de rendimiento en cierta clase de Java. Por ej. La clase Boolean prácticamente puede almacenar solo dos valores (verdadero o falso), pero un usuario puede crear múltiples objetos con el mismo valor usando new.

0

Después de ejecutar esa línea de código thing nunca va a hacer referencia a un objeto que existía antes de esa línea.

0

La llamada a new puede fallar si esta es la primera vez que se refiere a la clase y si la clase tiene bloques estáticos que no se pueden inicializar. He experimentado comportamientos en los que cualquier error de tiempo de ejecución que ocurra en un bloque o constructor estático dará lugar a que la nueva llamada genere una excepción ClassNotFound en el contexto de uso dentro del servidor de aplicaciones websphere. El cargador de clases de websphere aparentemente rechaza la carga de la clase debido a la excepción de tiempo de ejecución.

Cuestiones relacionadas