2010-07-21 11 views

Respuesta

11
getClass().getName() 

Actualización: Puede cargar el archivo de clase en un byte[] (utilizando el estándar de E/S) y luego usar getClass().getClassLoader().defineClass(...)

+0

no lo que le pedía, quiero leer la FQN desde el archivo .class, el objeto de clase no está cargado en la memoria. – TacB0sS

+0

@ TaCB0sS That * is * leyendo el nombre de clase del archivo .class. Creo que no entiendes tu propia pregunta. –

+0

Sé lo que quiero, simplemente no me di cuenta de que un nulo se puede pasar a defineClass. Gracias, Bozho! – TacB0sS

0

Dependiendo de qué IDE esté utilizando, podría haber un mecanismo para hacerlo. Por ejemplo, en eclipse, puede profundizar en el archivo .class y hacer clic derecho sobre él y seleccionar "copiar nombre completamente calificado".

Las versiones anteriores de Eclipse puede que no tienen esta característica, pero he utilizado este plugin antes:

http://www.jave.de/eclipse/copyfully/index.html

Funciona más o menos la misma manera. Espero que esto ayude.

+0

que es agradable, pero yo quiero esto en tiempo de ejecución realizado por mi solicitud – TacB0sS

2

Usar una biblioteca como BCEL para leer el archivo de clase en la memoria y consultarlo para el nombre de la clase.

+0

Esta no es la solución que tenía en mente, me gustaría leerla yo mismo, aunque gracias. – TacB0sS

+0

Luego, la respuesta de McDowell debería indicarle la dirección correcta. –

1

Puede leer esto analizando el binario. El class file format se define en el VM Spec.

Eche un vistazo a DataInputStream si es nuevo en el análisis de binarios.

0

Puede buscar, por ejemplo, en el AnnotationScanner desde la Implementación JSF, cargan las clases manualmente (para evitar la contaminación del espacio permanente) para encontrar anotaciones JSF. En particular vistazo a esto:

/** 
    * This class is encapsulating binary .class file information as defined at 
    * http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html 
    * <p/> 
    * This is used by the annotation frameworks to quickly scan .class files 
    * for the presence of annotations. This avoid the annotation framework 
    * having to load each .class file in the class loader. 
    * <p/> 
    * Taken from the GlassFish V2 source base. 
    */ 
    @SuppressWarnings({"UnusedDeclaration"}) 
    private static final class ClassFile { 

     private static final int magic = 0xCAFEBABE; 

     public static final int ACC_PUBLIC = 0x1; 
     public static final int ACC_PRIVATE = 0x2; 
     public static final int ACC_PROTECTED = 0x4; 
     public static final int ACC_STATIC = 0x8; 
     public static final int ACC_FINAL = 0x10; 
     public static final int ACC_SYNCHRONIZED = 0x20; 
     public static final int ACC_THREADSAFE = 0x40; 
     public static final int ACC_TRANSIENT = 0x80; 
     public static final int ACC_NATIVE = 0x100; 
     public static final int ACC_INTERFACE = 0x200; 
     public static final int ACC_ABSTRACT = 0x400; 

     public short majorVersion; 
     public short minorVersion; 
     public ConstantPoolInfo constantPool[]; 
     public short accessFlags; 
     public ConstantPoolInfo thisClass; 
     public ConstantPoolInfo superClass; 
     public ConstantPoolInfo interfaces[]; 

     /** 
     * bunch of stuff I really don't care too much for now. 
     * <p/> 
     * FieldInfo   fields[]; MethodInfo   methods[]; 
     * AttributeInfo  attributes[]; 
     */ 

     ByteBuffer header; 
     ConstantPoolInfo constantPoolInfo = new ConstantPoolInfo(); 

     // ------------------------------------------------------------ Constructors 


     /** 
     * Creates a new instance of ClassFile 
     */ 
     public ClassFile() { 
      header = ByteBuffer.allocate(12000); 
     } 

     // ---------------------------------------------------------- Public Methods 


     public void setConstantPoolInfo(ConstantPoolInfo poolInfo) { 
      constantPoolInfo = poolInfo; 
     } 


     /** 
     * Read the input channel and initialize instance data structure. 
     * 
     * @param in a <code>ReadableByteChannel</code> that provides the bytes 
     * of the classfile 
     * 
     * @return <code>true</code> if the bytes representing this classfile include 
     * one of the annotations we're looking for. 
     * 
     * @throws IOException if an I/O error occurs while reading the class 
     */ 
     public boolean containsAnnotation(ReadableByteChannel in) 
       throws IOException { 

      /** 
      * this is the .class file layout 
      * 
      ClassFile { 
      u4 magic; 
      u2 minor_version; 
      u2 major_version; 
      u2 constant_pool_count; 
      cp_info constant_pool[constant_pool_count-1]; 
      u2 access_flags; 
      u2 this_class; 
      u2 super_class; 
      u2 interfaces_count; 
      u2 interfaces[interfaces_count]; 
      u2 fields_count; 
      field_info fields[fields_count]; 
      u2 methods_count; 
      method_info methods[methods_count]; 
      u2 attributes_count; 
      attribute_info attributes[attributes_count]; 
      } 
      **/ 
      header.clear(); 
      long read = (long) in.read(header); 
      if (read == -1) { 
       return false; 
      } 
      header.rewind(); 

      if (header.getInt() != magic) { 
       return false; 
      } 

      minorVersion = header.getShort(); 
      majorVersion = header.getShort(); 
      int constantPoolSize = header.getShort(); 

      return constantPoolInfo 
        .containsAnnotation(constantPoolSize, header, in); 

     } 

    } // END ClassFile 
4
public String getFullClassName(String classFileName) throws IOException {   
     File file = new File(classFileName); 

     FileChannel roChannel = new RandomAccessFile(file, "r").getChannel(); 
     ByteBuffer bb = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, (int)roChannel.size());   

     Class<?> clazz = defineClass((String)null, bb, (ProtectionDomain)null); 
     return clazz.getName(); 
    } 
Cuestiones relacionadas