我很好奇,所以我做了自己的测试。我创建了java.util.concurrent 并使用此方法创建了一个Test 类:
public static Object getResult(CompletableFuture<?> cf) {
return cf.result;
}
然后我在 main 方法中的其他地方调用它。没有编译错误。运行导致这个:
线程“主”java.lang.SecurityException 中的异常:禁止
包名:java.util.concurrent at
java.lang.ClassLoader.preDefineClass(ClassLoader.java:662) 在
java.lang.ClassLoader.defineClass(ClassLoader.java:761) 在
java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
在 java.net.URLClassLoader.defineClass(URLClassLoader.java:467) 在
java.net.URLClassLoader.access$100(URLClassLoader.java:73) 在
java.net.URLClassLoader$1.run(URLClassLoader.java:368) 在
java.net.URLClassLoader$1.run(URLClassLoader.java:362) 在
java.security.AccessController.doPrivileged(Native Method) 在
java.net.URLClassLoader.findClass(URLClassLoader.java:361) 在
java.lang.ClassLoader.loadClass(ClassLoader.java:424) 在
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) 在
java.lang.ClassLoader.loadClass(ClassLoader.java:357) 在
sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)
所以,它似乎与类加载器有关......或者我认为......直到我看了ClassLoader.preDefineClass():
// Note: Checking logic in java.lang.invoke.MemberName.checkForTypeAlias
// relies on the fact that spoofing is impossible if a class has a name
// of the form "java.*"
if ((name != null) && name.startsWith("java.")) {
throw new SecurityException
("Prohibited package name: " +
name.substring(0, name.lastIndexOf('.')));
}
所以,它阻止了我,因为 Java 想要保护所有以 java 开头的包!
我去尝试了别的东西。我用这个方法添加了javafx.scene 包和另一个Test 类:
public static boolean getBoundsChange(Node n) {
return n.boundsChanged;
}
同样,没有编译错误,但它在运行时抛出这个:
原因:java.lang.IllegalAccessError: 试图访问字段
javafx.scene.Node.boundsChanged 来自类 javafx.scene.TestNode,位于
javafx.scene.TestNode.getBoundsChange(TestNode.java:7) 在
testFX.start(testFX.java:29) 在
com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
在
com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
在
com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
在 java.security.AccessController.doPrivileged(Native Method) 在
com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
在
com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
在 com.sun.glass.ui.win.WinApplication._runLoop(Native Method) 在
com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
... 1 更多
似乎 Java 确实可以防止这些,但仅在运行时这样做。
我在javafx.scene 中创建了另一个接口,并让它扩展Consumer<T>。我可以像原来的 Consumer<T> 一样使用它,所以没有什么能阻止我将这个包用于我的新课程。