在javax.swing.text.DefaultCaret.Handler.insertUpdate(DocumentEvent)的源代码中,我找到了以下行(从第1685行开始):
if (e instanceof AbstractDocument.UndoRedoDocumentEvent) {
setDot(offset + length);
return;
}但当我尝试这个:
package javax.swing.text;
public class Foo {
public static void main(String[] args) {
Object o = new Object();
if (o instanceof AbstractDocument.UndoRedoDocumentEvent) {
System.out.println("yay");
} else {
System.out.println("aww");
}
}
}它将提供:
Exception in thread "main" java.lang.IllegalAccessError: tried to access class javax.swing.text.AbstractDocument$UndoRedoDocumentEvent from class javax.swing.text.Foo
at javax.swing.text.Foo.main(Foo.java:6)为什么我不能instanceof反对那个类,但是DefaultCaret.Handler可以呢?
使用java版本1.6.0_20
$ java -version
java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.7) (6b20-1.9.7-0ubuntu1~10.04.1)
OpenJDK Client VM (build 19.0-b09, mixed mode, sharing)更新:
根据这些答案,我尝试了以下几点:
文件Foo.java
package javax.swing.text;
public class Foo {
public static void main(String[] args) {
Object o = new Object();
if (o instanceof Outer.Inner) {
System.out.println("yay");
} else {
System.out.println("aww");
}
}
}文件Outer.java
package javax.swing.text;
public class Outer {
class Inner {
}
}这工作很好,并打印"aww“如预期。
请注意,这两个文件都在包javax.swing.text中。还请注意,在我最初的问题中,Foo.java已经在包javax.swing.text中了。
据我所知,这个包裹没有“密封”。rt.jar的清单(包含包javax.swing.text的清单)不包含“密封”。命令Package.getPackage("javax.swing.text").isSealed()返回false。
因此,我可以针对我自己的内部类进行instance of,但不能针对AbstractDocument.UndoRedoDocumentEvent,即使包中的其他类也可以。
知道为什么会这样吗?
发布于 2011-04-09 17:55:39
看起来UndoRedoDocument是包保护的,DefaultCaret.Handler和UndoRedoDocument在同一个包中(如果我没记错的话,javax.swing.text)。
发布于 2011-04-09 17:56:15
第一个想法是,包javax.swing.text是密封的,您不允许向它添加新的类。你自己的包裹也是这样吗?
编辑:从我的评论:
有点晚,但我认为原因可能是您的类和swing类是由不同的类加载器加载的,来自不同类加载器的包并不是相同的包,即使它们的名称相同。
您可以了解Name.class.getClassLoader()或object.getClass().getClassLoader()使用哪个类加载器。把这些打印出来。( swing类的ClassLoader可能是null,它表示引导类加载器(由VM实现,在加载Class和ClassLoader类之前创建)。您的应用程序类加载程序很可能是另一个。
要使用自己的类加载器创建类,请使用URLClassLoader。这应该让应用程序的类加载器作为父类(允许类相互访问),但是使用另一个URL (例如,加载类不在通常的类路径上)。
你可以这样做:
Outer类放在应用程序的类路径中。类Main {公共静态空主(String[]忽略)抛出异常{ URL url =新URL("file:///path/to/other/dir");ClassLoader cl =新URLClassLoader(url,Main.class.getClassLoader());Class testClass = cl.loadClass("package.Test");testClass.getMethod("test").invoke(null);}
类测试{公共静态空测试(){ Object o=新对象();if (o instanceof Outer.Inner) { System.out.println("yay");} System.out.println("aww");}
如果我的理论是正确的,这应该是同样的例外。(我没有试过。)
https://stackoverflow.com/questions/5606757
复制相似问题