LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 276|回复: 0

Java - 深入理解注解

[复制链接]
发表于 2023-12-17 00:08:45 | 显示全部楼层 |阅读模式

深入理解注解
提示
接下来,我们从其它角度深入理解注解

# Java8提供了哪些新的注解?
@Repeatable
请参考Java 8 - 重复注解
ElementType.TYPE_USE
请参考Java 8 - 类型注解
ElementType.TYPE_PARAMETERElementType.TYPE_USE(此类型包括类型声明和类型参数声明,是为了方便设计者进行类型检查)包含了ElementType.TYPE(类、接口(包括注解类型)和枚举的声明)和ElementType.TYPE_PARAMETER(类型参数声明), 不妨再看个例子
// 自定义ElementType.TYPE_PARAMETER注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_PARAMETER)
public @interface MyNotEmpty {
}

// 自定义ElementType.TYPE_USE注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface MyNotNull {
}

// 测试类
public class TypeParameterAndTypeUseAnnotation<@MyNotEmpty T>{

  //使用TYPE_PARAMETER类型,会编译不通过
//                public @MyNotEmpty T test(@MyNotEmpty T a){
//                        new ArrayList<@MyNotEmpty String>();
//                                return a;
//                }

  //使用TYPE_USE类型,编译通过
  public @MyNotNull T test2(@MyNotNull T a){
    new ArrayList<@MyNotNull String>();
    return a;
  }
}


# 注解支持继承吗?

注解是不支持继承的

不能使用关键字extends来继承某个@interface,但注解在编译后,编译器会自动继承java.lang.annotation.Annotation接口.

虽然反编译后发现注解继承了Annotation接口,请记住,即使Java的接口可以实现多继承,但定义注解时依然无法使用extends关键字继承@interface。

区别于注解的继承,被注解的子类继承父类注解可以用@Inherited: 如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注解。

# 注解实现的原理?网上很多标注解的原理文章根本没有说到点子上。这里推荐你两篇文章:[url=https://blog.csdn.net/qq_20009015/article/details/106038023https://www.race604.com/annotation-processing/#]https://blog.csdn.net/qq_20009015/article/details/106038023[/url]
[url=https://blog.csdn.net/qq_20009015/article/details/106038023https://www.race604.com/annotation-processing/#]https://www.race604.com/annotation-processing/[/url]

注解的应用场景
提示
最后我们再看看实际开发中注解的一些应用场景。
@pdai# 配置化到注解化 - 框架的演进Spring 框架 配置化到注解化的转变。# 继承实现到注解实现 - Junit3到Junit4
一个模块的封装大多数人都是通过继承和组合等模式来实现的,但是如果结合注解将可以极大程度提高实现的优雅度(降低耦合度)。而Junit3 到Junit4的演化就是最好的一个例子。

被测试类

public class HelloWorld {
         
         public void sayHello(){
                 System.out.println("hello....");
                 throw new NumberFormatException();
         }
         
         public void sayWorld(){
                 System.out.println("world....");
         }
         
         public String say(){
                 return "hello world!";
         }
         
}
Junit 3 实现UT通过继承 TestCase来实现,初始化是通过Override父类方法来进行,测试方式通过test的前缀方法获取。

public class HelloWorldTest extends TestCase{
         private HelloWorld hw;
         
         @Override
         protected void setUp() throws Exception {
                 super.setUp();
                 hw=new HelloWorld();
         }
         
         //1.测试没有返回值
         public void testHello(){
                 try {
                         hw.sayHello();
                 } catch (Exception e) {
                         System.out.println("发生异常.....");
                 }
                 
         }
         public void testWorld(){
                 hw.sayWorld();
         }
         //2.测试有返回值的方法
         // 返回字符串
         public void testSay(){
                 assertEquals("测试失败", hw.say(), "hello world!");
         }
         //返回对象
         public void testObj(){
                 assertNull("测试对象不为空", null);
                 assertNotNull("测试对象为空",new String());
         }
         @Override
         protected void tearDown() throws Exception {
                 super.tearDown();
                 hw=null;
         }        
}
Junit 4 实现UT通过定义@Before,@Test,@After等等注解来实现。

public class HelloWorldTest {
         private HelloWorld hw;

         @Before
         public void setUp() {
                 hw = new HelloWorld();
         }

         @Test(expected=NumberFormatException.class)
         // 1.测试没有返回值,有别于junit3的使用,更加方便
         public void testHello() {
                 hw.sayHello();
         }
         @Test
         public void testWorld() {
                 hw.sayWorld();
         }
         
         @Test
         // 2.测试有返回值的方法
         // 返回字符串
         public void testSay() {
                 assertEquals("测试失败", hw.say(), "hello world!");
         }
         
         @Test
         // 返回对象
         public void testObj() {
                 assertNull("测试对象不为空", null);
                 assertNotNull("测试对象为空", new String());
         }

         @After
         public void tearDown() throws Exception {
                 hw = null;
         }

}
------
原文链接:https://pdai.tech/md/java/basic/java-basic-x-annotation.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表