代码之家  ›  专栏  ›  技术社区  ›  TacB0sS

如何读取.class文件的完全限定名

  •  7
  • TacB0sS  · 技术社区  · 15 年前

    嘿,我想标题是这样的,但仍然是。

    我需要 提取 这个 对象的完全限定名

    谢谢,
    亚当。

    6 回复  |  直到 15 年前
        1
  •  12
  •   Bozho    15 年前
    getClass().getName()
    

    更新: 可以将类文件加载到 byte[] (使用标准i/o),然后使用 getClass().getClassLoader().defineClass(...)

        2
  •  5
  •   Sergii Pozharov    15 年前
    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();
        }
    
        3
  •  2
  •   Tassos Bassoukos    15 年前

    使用像BCEL这样的库将类文件读入内存,并在其中查询类名。

        4
  •  1
  •   McDowell rahul gupta    15 年前
        5
  •  0
  •   Michael Bazos    15 年前

    根据您使用的IDE,可能有一种机制来实现这一点。例如,在eclipse中,您可以深入到.class文件,右键单击它并选择“复制完全限定名”。

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

    它的工作原理基本相同。希望这有帮助。

        6
  •  0
  •   mglauche    15 年前

    例如,您可以从JSF实现中查看AnnotationScanner,它们确实手动加载类(以避免perm空间污染)来查找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
    
    推荐文章