2010-07-21 26 views

回答

11
getClass().getName() 

更新:您可以在類文件加載到byte[](使用標準I/O),然後使用getClass().getClassLoader().defineClass(...)

+0

不是我問的,我想讀.class文件的FQN,類對象在運行時進行沒有加載到內存中。 – TacB0sS 2010-07-21 12:29:27

+0

@ TaCB0sS * *從* .class文件中讀取類名。我認爲你不明白你自己的問題。 – 2010-07-21 12:57:49

+0

我知道我想要什麼,我只是沒有意識到可以將null傳遞給defineClass。 謝謝,Bozho! – TacB0sS 2010-07-25 08:03:17

0

根據您使用的IDE,可能會有這樣的機制。例如在eclipse中,您可以深入到.class文件並右鍵單擊它並選擇「複製完全限定名稱」。

日食的舊版本可能沒有這個功能,但我之前已經使用這個插件:

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

它的工作原理幾乎相同的方式。希望這可以幫助。

+0

是不錯,但我想這在我的應用程序 – TacB0sS 2010-07-21 12:29:53

2

使用像BCEL圖書館閱讀類文件到內存中,並對其進行查詢爲類名稱。

+0

這不是我想到的解決方案,我想自己閱讀,謝謝。 – TacB0sS 2010-07-21 12:28:26

+0

然後McDowell的答案應該指向正確的方向。 – 2010-07-21 13:32:48

1

您可以通過解析二進制文件來閱讀。 class file formatVM Spec中定義。

如果您不熟悉解析二進制文件,請查看DataInputStream。

0

您可以從JSF實現的AnnotationScanner中看一個例子,他們會手動加載類(以避免泄漏空間污染)來查找JSF註釋。在這個特定的外觀:

/** 
    * 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(); 
    } 
相關問題