对注释进行类型转换-如何/为什么这样做?

你能帮我理解 (1) 的类型转换是如何/为什么工作的吗?我找不到任何表明 Java 注释类型可以类型转换为接口类型的内容。

org.junit.Test //this is an annotation
junit.framework.Test //this is an interface

只是我没有看到 org.junit.Test 和 junit.framework.Test 之间的关系

import org.junit.Test;
import junit.framework.AssertionFailedError;
import junit.framework.TestResult;
public class TestJunit3 extends TestResult {
   // add the error
   public synchronized void addError(Test test, Throwable t) {
      super.addError((junit.framework.Test) test, t); //how does this typecast work (1)
   }
   // add the failure
   public synchronized void addFailure(Test test, AssertionFailedError t) {
      super.addFailure((junit.framework.Test) test, t);
   }
   @Test
   public void testAdd() {
      // add any test
   }
   // Marks that the test run should stop.
   public synchronized void stop() {
      //stop the test here
   }
}

回答

根据Java 语言规范 (JLS) 第 9.6 章,注释是“一种特殊的接口类型”。事实上,它甚至说:

每个注解类型的直接超接口是java.lang.annotation.Annotation.

如果我们查看文档,我们可以看到它java.lang.annotation.Annotation实际上是一个接口。我可以在这里想到两种可能的情况,这将涉及摆脱我的头顶。请注意,这不是一个详尽的列表。有许多不同的方法来设计类型层次结构。

场景一

接口可以扩展任何其他接口,因此您可以拥有一个扩展注释的接口。然后你需要转换到子接口,像这样:

public @interface MyAnnotation { }

<

public interface MyInterface extends MyAnnotation { }

pre>public @interface MyAnnotation { }

public @interface MyAnnotation { }
public interface MyInterface extends MyAnnotation { }
public class MyClass implements MyInterface {
    // You have to implement the abstract method:
    @Override
    public Class<? extends Annotation> annotationType() {
        return MyAnnotation.class;
    }
}
public class Driver {
    public static void main(String[] args) {
        // Implicit cast to super:
        MyAnnotation annot = new MyClass();

        // Now we have to explicitly cast back down to an interface:
        MyInterface inter = (MyInterface) annot;
    }
}

场景二

将实例强制转换为其超类型之一应该是合法的。是的,这不是必需的,但它应该是合法的,因此您可以使用以下代码:

@MyAnnotation public class MyClass { }
public class Driver {
    public static void main(String[] args) {
        // Redundant, but legal cast:
        Annotation annot = (Annotation) MyClass.class.getAnnotations()[0];
    }
}

限制

请注意,JLS 说:

根据 AnnotationTypeDeclaration 语法,注释类型声明不能是通用的,并且不允许扩展子句。

这意味着您不能将注释作为除java.lang.annotation.Annotation.

JLS 还说:

注释类型不能显式声明超类或超接口这一事实的结果是,注释类型的子类或子接口本身永远不是注释类型。

这意味着以下代码将是非法的:

// Illegal because MyInterface is not an annotation type:
@MyInterface public class MyClass { }

你的场景

你有两个接口,org.junit.Testjunit.framework.Test. 是的,org.junit.Test是一个注解,但所有注解都是接口,正如我上面解释的那样。现在考虑一个实现两个接口的类:

public class MyClass implements org.junit.Test, junit.framework.Test {
    // You would have to implement all the methods here
}

考虑以下驱动程序代码,并注意从org.junit.Testto的合法、合法的强制转换junit.framework.Test

public class Driver {
    public static void main(String[] args) {
        // Implicit cast, because MyClass is a subtype of org.junit.Test:
        org.junit.Test test1 = new MyClass();

        // Here we need an explicit cast, but it's still legal.
        // test1 is still an instance of MyClass, so we can still cast it
        // to junit.framework.test
        junit.framework.Test test2 = (junit.framework.Test) test1;
    }
}

正如你在上面看到的,你可以创建一个类,它是org.junit.Testand的子类型junit.framework.Test,所以如果你在两者之间进行转换,编译器不会抱怨。如果您的类没有实现这两个接口,并且您尝试将实例转换为它没有实现的接口,您只会得到一个运行时异常。


以上是对注释进行类型转换-如何/为什么这样做?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>