针对javax.swing.text中的AbstractDocument.UndoRedoDocumentEvent尝试instanceof时出错

针对javax.swing.text中的AbstractDocument.UndoRedoDocumentEvent尝试instanceof时出错,java,instanceof,inner-classes,Java,Instanceof,Inner Classes,在javax.swing.text.DefaultCaret.Handler.insertUpdate(DocumentEvent)的源代码中,我找到了以下几行(从第1685行开始): 但当我尝试这个: package javax.swing.text; public class Foo { public static void main(String[] args) { Object o = new Object(); if (o instanceof

javax.swing.text.DefaultCaret.Handler.insertUpdate(DocumentEvent)
的源代码中,我找到了以下几行(从第1685行开始):

但当我尝试这个:

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");
        }
    }
}
package javax.swing.text;

public class Outer {
    class Inner {
    }
}
文件
Outer.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");
        }
    }
}
package javax.swing.text;

public class Outer {
    class Inner {
    }
}
这可以很好地工作并按预期打印“aww”

请注意,这两个文件都在包
javax.swing.text
中。还要注意,在我最初的问题中,
Foo.java
已经在包
javax.swing.text

据我所知,包裹没有“密封”。
rt.jar
(包含包
javax.swing.text
)的清单不包含“Sealed”。命令
Package.getPackage(“javax.swing.text”).isseald()
返回false

因此,我可以针对自己的内部类
实例,但不能针对
AbstractDocument.UndoRedoDocumentEvent
,即使包中的其他类也可以


你知道为什么吗?

看起来
undoredocument
是包保护的,
DefaultCaret.Handler
undoredocument
在同一个包中(
javax.swing.text
,如果我没记错的话)。

第一个想法是包javax.swing.text是密封的,并且不允许向其中添加新类。你自己的包裹也会发生同样的情况吗


编辑: 根据我的评论:


有点晚了,但我认为原因可能是您的类和swing类已加载 由不同的类加载器加载,而从不同的类加载器加载的包不会 被认为是相同的包,即使它们具有相同的名称

您可以找出
Name.class.getClassLoader()
object.getClass().getClassLoader()
所使用的类加载器。打印这些。(可能是swing类的类加载器是
null
,它表示引导类加载器(由VM实现,在
类和
类加载器加载之前创建)。您的应用程序类加载器很可能是另一个

要使用自己的类加载器创建类,请使用URLClassLoader。这应该将应用程序的类加载器作为父级(以允许类彼此访问),但要使用另一个URL(例如,加载不在常规类路径上的类)

你可以这样做:

class Main {
    public static void main(String[] ignored) throws Exception {
        URL url = new URL("file:///path/to/other/dir");
        ClassLoader cl = new URLClassLoader(url, Main.class.getClassLoader());
        Class<?> testClass = cl.loadClass("package.Test");
        testClass.getMethod("test").invoke(null);
    }
}
  • 外部
    类放入应用程序的类路径中
  • 创建一个主类(在相同的类路径中),如下所示:

    class Main {
        public static void main(String[] ignored) throws Exception {
            URL url = new URL("file:///path/to/other/dir");
            ClassLoader cl = new URLClassLoader(url, Main.class.getClassLoader());
            Class<?> testClass = cl.loadClass("package.Test");
            testClass.getMethod("test").invoke(null);
        }
    }
    

如果我的理论是正确的,这应该会给出相同类型的异常。(我没有尝试过。)

我尝试使用自己的类(和内部类)它成功了。虽然包似乎没有被密封。我更新了更多的信息。有点晚了,但我认为原因可能是您的类和swing类由不同的类加载器加载,而从不同的类加载器加载的包不被认为是同一个包,即使它们具有相同的name、 ŭloEbermann:还不算太晚。我仍然对答案感兴趣。是否可以检查哪个类加载了哪个类加载器?如果你解释一下我如何使用两个不同的类加载器使用自制类来复制错误消息,那将证明你的假设。