java - clases - crear un objeto de una clase dentro de otra clase




Implicaciones de eficiencia de clase anónima de Java (4)

¿Hay alguna diferencia en la eficiencia (por ejemplo, tiempo de ejecución, tamaño del código, etc.) entre estas dos formas de hacer las cosas?

A continuación se presentan ejemplos ideados que crean objetos y no hacen nada, pero mis escenarios reales pueden estar creando nuevos subprocesos, escuchas, etc. Supongamos que los siguientes fragmentos de código aparecen en un bucle para que pueda marcar la diferencia.

Usando objetos anónimos:

void doSomething() {
    for (/* Assume some loop */) {
        final Object obj1, obj2; // some free variables

        IWorker anonymousWorker = new IWorker() {
            doWork() {
                // do things that refer to obj1 and obj2
            }
        };
    }
}

Definiendo una clase primero:

void doSomething() {
    for (/* Assume some loop */) {
        Object obj1, obj2;
        IWorker worker = new Worker(obj1, obj2);
    }
}

static class Worker implements IWorker {
    private Object obj1, obj2;
    public CustomObject(Object obj1, Object obj2) {/* blah blah */}

    @Override
    public void doWork() {}
};

Con respecto al rendimiento, debe considerar si se debe crear una clase interna o no crearla.

Un ejemplo de mala práctica es algo como:

public List<String> someMethod() {
       return new ArrayList<String>() {{
                      add("Item one");
                      add("Item two");
              }};
}

Si bien esta conveniencia sintáctica parece inteligente a primera vista, esta (a menudo inadvertida) crea una clase interna anónima cuyo objeto mantiene una referencia a la instancia externa. Como este objeto también se entrega al exterior como valor de resultado de algún Método, no puede estar seguro de qué hace su llamante con esta lista. Si coloca la instancia de ArrayList resultante en una variable estática, ¡su Objeto actual se mantendrá para siempre también!


Debe haber poca o ninguna diferencia de rendimiento. Si hay una diferencia, estará en un nivel en el que no vale la pena preocuparse.

En mi opinión, debe centrarse en escribir código que sea legible y fácil de mantener, e ignorar los problemas de rendimiento "micro" hasta que tenga pruebas claras de que son importantes ... según el perfil de la aplicación.

(Para el registro, cuando una clase interna anónima se refiere a una final en un ámbito cerrado, esto se implementa a nivel de bytecode por medio de argumentos de constructor ocultos y atributos de instancia ocultos. Los bytecodes serán casi los mismos que los bytecodes que obtiene de su otra implementación.)


Es importante darse cuenta de que las clases anónimas aún son clases que se conocieron y se compilaron completamente en tiempo de compilación. El hecho de que, por ejemplo, está definiendo un cuerpo de clase anónimo, quizás con muchos métodos y campos, etc. dentro de un bucle, no significa que el tiempo de ejecución tenga que compilar ese tipo en cada iteración.

Por lo tanto, cualquier diferencia en el rendimiento entre los dos enfoques es despreciable. Los factores importantes a considerar son cosas como la legibilidad, la reutilización, la capacidad de prueba, etc.


Especular sobre el rendimiento del código es una excelente manera de perder el tiempo. Nada se compara con realmente comparar el código. Si te preocupa el rendimiento, mide el código . Si sospecha que su código es subóptimo, haga un perfil del código para averiguar dónde se gasta el tiempo, luego intente mejorar esas partes. En este momento, puede ser apropiado estudiar realmente el código de byte para ver si eso puede darle una pista de qué implementación es más eficiente.

Cuando haya hecho eso, mida el código nuevamente para asegurarse de que no empeoró las cosas, por ejemplo, haciendo que el código sea más feo y más difícil de mantener.





execution-time