2011-04-05 20 views
26

¿Cómo puedo habilitar programáticamente assert para clases particulares, en lugar de especificar el parámetro de línea de comando "-ea"?¿Cómo habilitar programáticamente assert?

public class TestAssert { 

    private static final int foo[] = new int[]{4,5,67}; 


    public static void main(String []args) { 
     assert foo.length == 10; 
    } 
} 

Respuesta

8

Esto fue un comentario a la buena respuesta de @bala, pero se hizo demasiado largo.

Si solo habilita las afirmaciones, llame a su clase principal: su clase principal se cargará antes de que se activen las aserciones, por lo que probablemente necesite un cargador que no haga referencia directa a ninguna otra cosa en su código. Puede establecer las aserciones y luego cargar el resto del código a través de la reflexión.

Si las aserciones no están habilitadas cuando se carga la clase, entonces deben ser "compiladas" inmediatamente para que no pueda activarlas y desactivarlas. Si quiere alternar entre ellos, entonces no quiere aserciones en absoluto.

Debido a la compilación en tiempo de ejecución, algo como esto:

public myAssertNotNull(Object o) { 
    if(checkArguments) 
     if(o == null) 
      throw new IllegalArgumentException("Assertion Failed"); 
} 

debería funcionar casi tan rápido como afirmaciones porque si el código se ejecuta mucho y checkArguments es falsa y no cambia entonces toda la llamada al método podría compilarse en el tiempo de ejecución, que tendrá el mismo efecto básico que una aserción (Este rendimiento depende de la máquina virtual).

13

Trate

ClassLoader loader = getClass().getClassLoader(); 
setDefaultAssertionStatus(true); 

o

ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); 

EDIT:

basado en los comentarios

ClassLoader loader = ClassLoader.getSystemClassLoader(); 
    loader.setDefaultAssertionStatus(true); 
    Class<?> c = loader.loadClass("MyClass"); 
    MyClass myObj = (MyClass) c.newInstance(); 


public class MyClass { 

    private static final int foo[] = new int[]{4,5,67}; 
    MyClass() 
    { 
     assert foo.length == 10; 
    } 
} 
+0

Como puede ver la imagen "Basado en comentarios", no funciona después de que el comentario se haya marcado como obsoleto, por lo que es mejor documentar el motivo correctamente. ¿Por qué creas una instancia de MyClass a través de la reflexión? –

2

El más simple & mejor manera puede ser:

public static void assertion(boolean condition,String conditionFailureMessage) 
{ 
    if(!b) 
     throw new AssertionError(conditionFailureMessage); 
} 

No hay necesidad de establecer -ea como argumento de VM.

llamada de la función como:

assertion(sum>=n,"sum cannot be less than n"); 

Si aserción falla, el código dará AssertionError, código más va a ejecutar de forma segura.

+0

El punto de las afirmaciones es que pueden activarse o no en el JRE, de modo que una declaración 'assert x' tiene un efecto o no. Esto no es posible con tu sugerencia. –