una tipos que modificadores metodos metodo elementos ejemplos clases clase acceso java jvm

java - tipos - ¿Cómo asegurarse de que solo hay una instancia de clase en JVM?



tipos de clases en java (9)

Solo puedo pensar en una forma de contar instancias de una clase y destruir todas las instancias después de que se crea la primera. ¿Es este un enfoque correcto? Si no, ¿hay alguna otra manera?

El enfoque técnico correcto es declarar que todos los constructores de la clase son private para que las instancias de la clase solo puedan ser creadas por la clase en sí. Luego codificas la clase solo creas una instancia.

Otras respuestas muestran algunas de las formas de implementar esto, de acuerdo con el patrón de diseño "Singleton". Sin embargo, la implementación de un singleton como este tiene algunos inconvenientes, que incluyen que sea mucho más difícil escribir pruebas unitarias.

Estoy desarrollando un patrón de diseño, y quiero asegurarme de que aquí solo hay una instancia de una clase en la Máquina Virtual Java, para canalizar todas las solicitudes de algún recurso a través de un solo punto, pero no sé si es posible.

Solo puedo pensar en una forma de contar instancias de una clase y destruir todas las instancias después de que se crea la primera.

¿Es este un enfoque correcto? Si no, ¿hay alguna otra manera?


Ese es el conocido patrón de Singleton: puede implementarlo de la siguiente manera:

public class SingletonClass { //this field contains the single instance every initialized. private static final instance = new SingletonClass(); //constructor *must* be private, otherwise other classes can make an instance as well private SingletonClass () { //initialize } //this is the method to obtain the single instance public static SingletonClass getInstance () { return instance; } }

Luego llama a la instancia (como si estuvieras construyendo un no-singleton) con:

SingletonClass.getInstance();

Pero en literatura, un Singleton en general se considera una mala idea de diseño . Por supuesto, esto siempre depende en cierta medida de la situación, pero la mayoría de los programadores lo desaconsejan. Solo diciéndolo, no dispares al mensajero ...


Hay una escuela de pensamiento que considera que el patrón de Singleton es, de hecho, un antipatrón.

Teniendo en cuenta una clase A de la que solo desea tener una, una alternativa es tener un generador o una clase de fábrica que limite la creación del número de objetos de la Clase A, y que podría ser mediante un simple contador. La ventaja es que la Clase A ya no necesita preocuparse por eso, se concentra en su propósito real. Cada clase que lo usa ya no tiene que preocuparse de que sea un singleton (tampoco más llamadas getInstance ()).


Para eso necesitas usar el patrón de singleton, solo estoy publicando un código de demostración que puede ser útil para tu comprensión.

Por ejemplo: si quiero solo un objeto para esta clase de Connect :

public final class Connect { private Connect() {} private volatile static Connect connect = null; public static Connect getinstance() { if(connect == null) { synchronized (Connect.class) { connect = new Connect(); } } return connect; } }

Aquí el constructor es privado, por lo que nadie puede usar una new palabra clave para crear una nueva instancia.


Prefiero la clase singleton perezosa, que anula el método readResolve .

Para las clases Serializable y Externalizable, el método readResolve permite que una clase reemplace / resuelva el objeto leído de la secuencia antes de que se devuelva al llamante. Al implementar el método readResolve, una clase puede controlar directamente los tipos e instancias de sus propias instancias que se deserializan.

Singleton perezoso utilizando /Initialization-on-demand_holder_idiom :

public final class LazySingleton { private LazySingleton() {} public static LazySingleton getInstance() { return LazyHolder.INSTANCE; } private static class LazyHolder { private static final LazySingleton INSTANCE = new LazySingleton(); } private Object readResolve() { return LazyHolder.INSTANCE; } }

Notas clave:

  1. final palabra clave final prohíbe la extensión de esta clase por subclasificación
  2. private constructor private prohíbe la creación directa de objetos con un new operador en clases de llamantes
  3. readResolve prohíbe la creación de múltiples instancias de clase durante la readResolve de objetos

Quieres el patrón Singleton . Hay una excelente discusión sobre cómo implementar esto correctamente. Si haces esto bien, solo habrá una instancia de la clase.

Esencialmente, lo que vas a hacer es crear una clase, mantener un solo objeto instanciado de esa clase en el nivel estático y proporcionar un acceso estático para obtenerlo ( getInstance() o similar). Haga que el constructor sea final para que las personas no puedan crear sus propias instancias de la nada. Ese enlace de arriba tiene muchos consejos excelentes sobre cómo hacer esto.


Utilice el patrón de singleton . La implementación más sencilla consiste en un private constructor y un field para mantener su resultado, y un método de acceso static con un nombre como getInstance() .

El campo privado se puede asignar desde un bloque de inicializador estático o, más simplemente, mediante un inicializador. El método getInstance() (que debe ser público) simplemente devuelve esta instancia,

public class Singleton { private static Singleton instance; /** * A private Constructor prevents any other class from * instantiating. */ private Singleton() { // nothing to do this time } /** * The Static initializer constructs the instance at class * loading time; this is to simulate a more involved * construction process (it it were really simple, you''d just * use an initializer) */ static { instance = new Singleton(); } /** Static ''instance'' method */ public static Singleton getInstance() { return instance; } // other methods protected by singleton-ness would be here... /** A simple demo method */ public String demoMethod() { return "demo"; } }

Tenga en cuenta que el método de usar "evaluación perezosa" en el método getInstance() (que se recomienda en los patrones de diseño), no es necesario en Java porque Java ya usa "carga diferida". Es probable que su clase de singleton no se cargue a menos que sea getInstance() se llama, por lo que no tiene sentido tratar de diferir la construcción de singleton hasta que sea necesario haciendo que getInstance() pruebe la variable de singleton para null y cree el singleton allí.

Usar esta clase es igual de simple: simplemente obtenga y conserve la referencia, e invoque métodos en ella:

public class SingletonDemo { public static void main(String[] args) { Singleton tmp = Singleton.getInstance(); tmp.demoMethod(); } }

Algunos comentaristas creen que un singleton también debería proporcionar un método clone() final público que solo lanza una excepción, para evitar las subclases que "hacen trampa" y clone() el singleton. Sin embargo, está claro que una clase con solo un constructor privado no puede ser subclasificada, por lo que esta paranoia no parece ser necesaria.



class A{ private A(){ } public static A creator(A obj){ A ob=new A(); return ob; } void test(){ System.out.println("The method is called"); } } class Demo{ public static void main(String[] args){ A ob=null; ob=A.creator(ob); ob.test(); } }