java 如何读取 .class 文件的完全限定名称
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3298954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to read the fully qualified name of a .class file
提问by TacB0sS
Hey, I think the title sums it, but still.
嘿,我认为标题总结了它,但仍然如此。
I need to extractthe fully qualified name of an objectfrom its compiled .classfile, could anyone point me in the right direction?
我需要从编译的.class文件中提取对象的完全限定名称,有人能指出我正确的方向吗?
Thanks,
Adam.
谢谢,
亚当。
回答by Bozho
getClass().getName()
Update:You can load the class-file into a byte[](using standard i/o) and then use getClass().getClassLoader().defineClass(...)
更新:您可以将类文件加载到byte[](使用标准 i/o)中,然后使用getClass().getClassLoader().defineClass(...)
回答by Sergii Pozharov
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();
}
回答by Tassos Bassoukos
Use a library like BCEL to read the classfile into memory and query it for the class name.
使用像 BCEL 这样的库将类文件读入内存并查询类名。
回答by McDowell
You can read this by parsing the binary. The class file formatis defined in the VM Spec.
您可以通过解析二进制文件来阅读此内容。在类文件格式中定义的VM规格。
Have a look at the DataInputStream if you're new to parsing binaries.
如果您不熟悉解析二进制文件,请查看 DataInputStream。
回答by mglauche
You can take a look for example at the AnnotationScanner from the JSF Implementation, they do load the classes manually (to avoid perm-space pollution) to find JSF annotations. In particular look at this:
您可以从 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
回答by Michael Bazos
Depending on what IDE you are using there might be a mechanism for doing this. For example in eclipse you can drill down to the .class file and right click on it and select "copy fully qualified name".
根据您使用的 IDE,可能有一种机制可以做到这一点。例如,在 eclipse 中,您可以深入到 .class 文件并右键单击它并选择“复制完全限定名称”。
Older versions of eclipse might not have this feature, but I have used this plugin before:
旧版本的eclipse可能没有这个功能,但是我之前用过这个插件:
http://www.jave.de/eclipse/copyfully/index.html
http://www.jave.de/eclipse/copyfully/index.html
It works pretty much the same way. Hope this helps.
它的工作方式几乎相同。希望这可以帮助。

