java instanceof和getClass()不能按预期工作

时间:2013-11-26 06:20:49

标签: java inheritance

我有以下代码:

protected LogEvent toLogEvent(LogRecord element) {
    ......
    System.out.println("element.getClass():"+element.getClass());
    System.out.println("element.getClass() == org.jboss.logmanager.ExtLogRecord.class:" + (element.getClass() == org.jboss.logmanager.ExtLogRecord.class));
    System.out.println("element instanceof org.jboss.logmanager.ExtLogRecord:" + (element instanceof org.jboss.logmanager.ExtLogRecord));
    System.out.println("element instanceof java.util.logging.LogRecord:"+(element instanceof java.util.logging.LogRecord));
    System.out.println("element.toString():"+element.toString());

输出结果为:

09:20:51,544 INFO  stdout element.getClass():class org.jboss.logmanager.ExtLogRecord
09:20:51,545 INFO  stdout element.getClass() ==org.jboss.logmanager.ExtLogRecord.class:false
09:20:51,547 INFO  stdout element instanceof org.jboss.logmanager.ExtLogRecord:false
09:20:51,548 INFO  stdout element instanceof java.util.logging.LogRecord:true
09:20:51,549 INFO  stdout element.toString():org.jboss.logmanager.ExtLogRecord@2657c0ad

ExtLogRecordLogRecord的子类。

我的问题是:

  1. 在第二行中为什么输出为false? clear元素是ExtLogRecord的实例。

  2. 在第三行元素instanceof ExtLogRecord中返回false,在第四行元素instanceof LogRecord中返回true。因此元素是LogRecord,但它不是ExtLogRecord。这是怎么回事?

  3. 更新

    我添加了一些关于类加载的附加代码。输出是:

    10:32:48,372 INFO  stdout (new ExtLogRecord()) instanceof  ExtLogRecord:true
    10:32:48,374 INFO  stdout new ExtLogRecord(org.jboss.logmanager.Level.ALL,"","").getClass():class org.jboss.logmanager.ExtLogRecord
    10:32:48,376 INFO  stdout LogRecord.class.getClassLoader():null
    10:32:48,377 INFO  stdout ExtLogRecord.class.getClassLoader():"ModuleClassLoader for Module "org.tamin.tiba.logging.jboss.handlers:main" from local module loader@416a8198(roots: D:\java\jbossas\modules)
    10:32:48,378 INFO  stdout LogRecord.class.getClassLoader() == ExtLogRecord.class.getClassLoader():false
    

    更新2:

    其他类加载比较:

    10:43:14,113 INFO  stdout element.getClass().getClassLoader() == ExtLogRecord.class.getClassLoader():false
    10:43:14,115 INFO  stdout element.getClass().getClassLoader():ModuleClassLoader for Module "org.jboss.logmanager:main" from local module loader @576fb9a5 (roots: D:\java\jbossas\modules)
    

2 个答案:

答案 0 :(得分:6)

当您传递LogRecord实例而不是子类实例时,您将获得这些输出。考虑这两个类,并假设它们有一个0-arg构造函数,下面是调用带有2个实例的方法的结果:

toLogEvent(new LogRecord());     // passing superclass instance
System.out.println();
toLogEvent(new ExtLogRecord());  // passing subclass instance

输出:

element.getClass():class LogRecord
element.getClass() == ExtLogRecord.class:false
element instanceof ExtLogRecord:false
element instanceof LogRecord:true
element.toString():LogRecord@182f0db

element.getClass():class ExtLogRecord
element.getClass() == ExtLogRecord.class:true  
element instanceof ExtLogRecord:true  
element instanceof LogRecord:true
element.toString():ExtLogRecord@192d342

输出很明显。超类的实例不是也不能是其任何子类的实例。同样,LogRecord.class不能等于ExtLogRecord.class

答案 1 :(得分:1)

  • 由于LogRecord.class不相等,您的第二行输出为false 到ExtLogRecord.class。您正在传递LogRecord实例和 对其子类进行等式检查

  • 您的第三行输出为false,因为父类实例不能 它的子类

  • 的一个实例
  • 您的第四行输出为true,因为它是LogRecord的一个实例 类

希望有所帮助