Как прочитать полное имя файла .class

Эй, я думаю, название суммирует это, но все же.

Мне нужно извлечь полное имя объекта из его скомпилированного файла .class. Может ли кто-нибудь указать мне правильное направление?

Спасибо,
Адам.


person TacB0sS    schedule 21.07.2010    source источник


Ответы (5)


getClass().getName()

Обновление: вы можете загрузить файл класса в byte[] (используя стандартный ввод-вывод), а затем использовать getClass().getClassLoader().defineClass(...)

person Bozho    schedule 21.07.2010
comment
не то, что я просил, я хочу прочитать fqn из файла .class, объект класса не загружается в память. - person TacB0sS; 21.07.2010
comment
@ TaCB0sS Это чтение имени класса из файла .class. Я думаю, вы не понимаете своего вопроса. - person Noon Silk; 21.07.2010
comment
Я знаю, чего хочу, я просто не понимал, что null можно передать в defineClass. Спасибо, Божо! - person TacB0sS; 25.07.2010

Используйте такую ​​библиотеку, как BCEL, для чтения файла класса в память и запроса имени класса.

person Tassos Bassoukos    schedule 21.07.2010
comment
Это не то решение, которое я имел в виду, я бы сам хотел его прочитать, хотя спасибо. - person TacB0sS; 21.07.2010
comment
Тогда ответ Макдауэлла должен указать вам правильное направление. - person Tassos Bassoukos; 21.07.2010

Вы можете прочитать это, проанализировав двоичный файл. Определен формат файла класса в спецификации ВМ.

Взгляните на DataInputStream, если вы новичок в синтаксическом анализе двоичных файлов.

person McDowell    schedule 21.07.2010

В зависимости от того, какую IDE вы используете, для этого может быть механизм. Например, в eclipse вы можете перейти к файлу .class, щелкнуть его правой кнопкой мыши и выбрать «копировать полное имя».

Более старые версии eclipse могут не иметь этой функции, но я использовал этот плагин раньше:

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

Это работает примерно так же. Надеюсь это поможет.

person Michael Bazos    schedule 21.07.2010
comment
это хорошо, но я хочу, чтобы это выполнялось моим приложением во время выполнения. - person TacB0sS; 21.07.2010

Вы можете взглянуть, например, на AnnotationScanner из реализации JSF, они действительно загружают классы вручную (чтобы избежать загрязнения постоянного пространства), чтобы найти аннотации 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
person mglauche    schedule 21.07.2010