是的,只要您正确实施ForwardingJavaFileManager
. 两个最重要的方法是inferBinaryName()和list()。如果您正确设置这两个,编译器将能够解析您之前编译的类。
inferBinaryName()
必须返回类的简单名称(例如推断的二进制名称com.test.Test
将是 just Test
)。这是我的实现(我的子类JavaFileObject
被称为InAppJavaFileObject
):
@Override
public String inferBinaryName(Location location, JavaFileObject javaFileObject) {
if(location == StandardLocation.CLASS_PATH && javaFileObject instanceof InAppJavaFileObject) {
return StringUtils.substringBeforeLast(javaFileObject.getName(), ".java");
}
return super.inferBinaryName(location, javaFileObject);
}
请注意,我从最后剥离了“.java”。构造时JavaFileObject
,文件名必须以“.java”结尾,但如果你以后不去掉后缀,编译器将找不到你的类。
list()
有点复杂,因为您必须小心地与您的委托文件管理器一起玩。在我的实现中,我将完全限定的类名映射到JavaFileObject
我可以迭代的子类:
@Override
public Iterable<JavaFileObject> list(Location action, String pkg, Set<JavaFileObject.Kind> kind, boolean recurse) throws IOException {
Iterable<JavaFileObject> superFiles = super.list(action, pkg, kind, recurse);
// see if there's anything in our cache that matches the criteria.
if(action == StandardLocation.CLASS_PATH && (kind.contains(JavaFileObject.Kind.CLASS) || kind.contains(JavaFileObject.Kind.SOURCE))) {
List<JavaFileObject> ourFiles = new ArrayList<JavaFileObject>();
for(Map.Entry<String,InAppJavaFileObject> entry : files.entrySet()) {
String className = entry.getKey();
if(className.startsWith(pkg) && ("".equals(pkg) || pkg.equals(className.substring(0, className.lastIndexOf('.'))))) {
ourFiles.add(entry.getValue());
}
}
if(ourFiles.size() > 0) {
for(JavaFileObject javaFileObject : superFiles) {
ourFiles.add(javaFileObject);
}
return ourFiles;
}
}
// nothing found in our hash map that matches the criteria... return
// whatever super came up with.
return superFiles;
}
一旦您正确实施了这些方法,其余的就可以工作了。享受!