Эй, я думаю, название суммирует это, но все же.
Мне нужно извлечь полное имя объекта из его скомпилированного файла .class. Может ли кто-нибудь указать мне правильное направление?
Спасибо,
Адам.
Эй, я думаю, название суммирует это, но все же.
Мне нужно извлечь полное имя объекта из его скомпилированного файла .class. Может ли кто-нибудь указать мне правильное направление?
Спасибо,
Адам.
getClass().getName()
Обновление: вы можете загрузить файл класса в byte[]
(используя стандартный ввод-вывод), а затем использовать getClass().getClassLoader().defineClass(...)
Используйте такую библиотеку, как BCEL, для чтения файла класса в память и запроса имени класса.
Вы можете прочитать это, проанализировав двоичный файл. Определен формат файла класса в спецификации ВМ.
Взгляните на DataInputStream, если вы новичок в синтаксическом анализе двоичных файлов.
В зависимости от того, какую IDE вы используете, для этого может быть механизм. Например, в eclipse вы можете перейти к файлу .class, щелкнуть его правой кнопкой мыши и выбрать «копировать полное имя».
Более старые версии eclipse могут не иметь этой функции, но я использовал этот плагин раньше:
http://www.jave.de/eclipse/copyfully/index.html
Это работает примерно так же. Надеюсь это поможет.
Вы можете взглянуть, например, на 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