2010-07-21 136 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(); 
    } 
相关问题