Pregunta

Busco brindar cierta conveniencia a través de la reflexión para los programadores que usarán mi código. Para lograr el resultado deseado, me gustaría obtener el objeto de clase para las clases que extienden mi código. Aunque no pueden anular el método estático del que deseo acceder a la información, actualmente sería útil. Puede que termine simplemente refactorizando el diseño un poco para evitar esta situación, pero quería lanzar esta pregunta a la comunidad.

La única forma de lograr esto que conozco es tomar el hilo actual, navegar por el seguimiento de la pila y extraer el nombre de la clase, luego convertirlo en una instancia real de la clase.

¿Alguna otra sugerencia?

Nota al margen: el enfoque anterior también es la única forma en que soy consciente de obtener el método de llamada.

¿Fue útil?

Solución

Cuando está en el método estático, ¿cuál es la garantía de que alguna (cualquier) clase que se haya extendido desde la suya esté en la pila?

Si piensa en esto un poco, sospecho que se dará cuenta de que lo que está buscando no existe.

/ EDIT 1 / Creo que lo que necesitas es

abstract class B {
    <T extends B> B create(Class<T> clazz) {
    ....
}

Hmmm. ¿Qué sucede si create es el método protegido ? Entonces podría estar bastante seguro de que la persona que llama es un B , incluso puede solicitarlo, lanzando UnsupportedOperation o IllegalState si la persona que llama no es asignable a B .

Puedes usar Thread.currentThread (). getStackTrace ()

Otros consejos

Lamentablemente, caminar por la pila no es necesariamente seguro:

Desde el Javadoc JDK 6 para getStackTrace:

  

Algunas máquinas virtuales pueden, bajo algunas   circunstancias, omita una o más pilas   Marcos de la traza de la pila. En el   caso extremo, una máquina virtual que   no tiene información de seguimiento de pila   en relación con este tirable está permitido   para devolver una matriz de longitud cero desde   este método. En general, el   matriz devuelta por este método será   contiene un elemento para cada cuadro   que sería impreso por   printStackTrace.

Podrías, quizás, usar la api del depurador para hacerlo. Creo que las cosas de depuración son capaces de usar HotSpot a toda velocidad (podría estar equivocado), por lo que no verías un golpe de velocidad masivo por hacerlo. Puede comenzar mirando: http: // java .sun.com / javase / 6 / docs / technotes / guides / jpda / trace.html

También, basándose en la respuesta Sin respuesta ...

class Base
{
    // instance method helper
    public final int foo()
    {
        return (foo(this.getClass()));
    }

    // the real helper, with access to the class
    private static int foo(final Class clazz)
    {
        return (0);
    }
}

class Child
    extends Base
{
    public void bar()
    {
        final int x;

        x = foo();
    }
}

Crear un Throwable es muy costoso, así que no lo uses si llamas a tu método con frecuencia (por ejemplo, más de una vez por segundo) Un enfoque ligeramente mejor es Thread.currentThread (). GetStackTrace ().

Otro enfoque si está utilizando la JVM de Sun es Reflection.getCallerClass (n). Esto es mucho más rápido pero no portátil a otras JVM. Si le preocupa esto, podría tener otro método que lo llame si está disponible y, si no lo está, utiliza el seguimiento de la pila.

Todo esto supone que tu método estático NO es público. Si es así, todas las apuestas están desactivadas, ya que cualquier clase puede invocar tu método, no solo una que sea la tuya.

Sugiero evitar el atolladero de la reflexión. Pareces estar haciendo algún tipo de programación directa. Use una implementación sencilla (no hay suficiente información para hacer una estimación razonable de lo que podría ser).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top