对于我的用例,我想通过Socket连接传输一个类(不是对象,实际的类文件),然后在接收端加载该类。
该类通常包含在项目中(在发送端),因此它在类路径上的某处。
我已经完成了所有代码,但实际上从类路径中获取类文件,我不得不采取一些奇怪的方法将类作为资源(代码被剥离到必要部分):
public class ClassTransport {
public byte[] data;
public String qualifiedName;
public static ClassTransport create(Class<?> theClass) throws Exception {
ClassTransport result = new ClassTransport();
result.qualifiedName = theClass.getName();
// brute force derive the class file name
String classResourceName = theClass.getName().replace('.', '/') + ".class";
ClassLoader cl = theClass.getClassLoader();
try (InputStream in = cl.getResourceAsStream(classResourceName)) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
int b;
while ((b = in.read()) >= 0) {
out.write(b);
}
out.close();
result.data = out.toByteArray();
}
return result;
}
}
这是有效的,但它实际上是安全这样做还是违反了任何规范 - 特别是在将来失败来检索课程的可能性是什么JRE发布还是在特定平台上发布?
答案 0 :(得分:1)
简短的回答:这可能很好。
更长的答案:它不能保证没问题,因为JLS中的任何内容都不能保证包中的类被组织为目录中的文件。
JLS的相关部分是7.2. Host Support for Packages:
在Java SE平台的简单实现中,包和编译单元可以存储在本地文件系统中。其他实现可以使用分布式文件系统或某种形式的数据库来存储它们。
如果主机系统在数据库中存储包和编译单元,则数据库不得对基于文件的实现中允许的编译单元施加可选限制(第7.6节)。
要点是,理论上,类路径可能类似于数据库而不是文件系统。因此,虽然您的方法不会违反任何规范,但任何规范都不会支持。我找不到任何这种情况的系统,所以你可能好吧假设在大多数情况下使用文件系统。
这也在this StackOverflow问题中进行了讨论。