昆明java培训
达内昆明广州春城路

18487146383

热门课程

java程序建议:小心注解继承

  • 时间:2016-09-28
  • 发布:昆明Java培训
  • 来源:达内新闻

昆明Java培训机构的老师今天给大家讲java的注解继承

Java从1.5版本开始引入注解(Annotation),其目的是在不影响代码语义的情况下增强代码的可读性,并且不改变代码的执行逻辑,对于注解始终有两派争论,正方认为注解有益于数据与代码的耦合,"在有代码的周边集合数据";反方认为注解把代码和数据混淆在一起,增加了代码的易变性,消弱了程序的健壮性和稳定性。这些争论暂且搁置,昆明Java培训机构的老师要说的是一个我们不常用的元注解(Meta-Annotation):@Inheruted,它表示一个注解是否可以自动继承,我们开看它如何使用。

思考一个例子,比如描述鸟类,它有颜色、体型、习性等属性,昆明Java培训机构的老师以颜色为例,定义一个注解来修饰一下,代码如下:

1 import java.lang.annotation.ElementType;

2 import java.lang.annotation.Inherited;

3 import java.lang.annotation.Retention;

4 import java.lang.annotation.RetentionPolicy;

5 import java.lang.annotation.Target;

6

7 @Retention(RetentionPolicy.RUNTIME)

8 @Target(ElementType.TYPE)

9 @Inherited

10 public @interface Desc {

11    enum Color {

12        White, Grayish, Yellow

13    }

14

15    //默认颜色是白色的

16    Color c() default Color.White;

17 }

该注解Desc前增加了三个注解:Retention表示的是该注解的保留级别,Target表示的是注解可以标注在什么地方,@Inherited表示该注解会被自动继承。注解定义完毕,我们把它标注在类上,代码如下:

1 @Desc(c = Color.White)

2 abstract class Bird {

3    public abstract Color getColor();

4 }

5

6 //麻雀

7 class Sparrow extends Bird {

8    private Color color;

9

10    //默认是浅灰色

11    public Sparrow() {

12        color = Color.Grayish;

13    }

14

15    //构造函数定义鸟的颜色

16    public Sparrow(Color _color) {

17        color = _color;

18    }

19

20    @Override

21    public Color getColor() {

22        return color;

23    }

24 }

25

26 //鸟巢,工厂方法模式

27 enum BirdNest {

28    Sparrow;

29    //鸟类繁殖

30    public Bird reproduce() {

31        Desc bd = Sparrow.class.getAnnotation(Desc.class);

32        return bd == null ? new Sparrow() : ew Sparrow(bd.c());

33    }

34 }

上面程序声明了一个Bird抽象类,并且标注了Desc注解,描述鸟类的颜色是白色,然后编写一个麻雀Sparrow类,它有两个构造函数,一个是默认的构造函数,也就是我们经常看到的麻雀是浅灰色的,另外一个构造函数是自定义麻雀的颜色,之后又定义了一个鸟巢(工厂方法模式),它是专门负责鸟类繁殖的,它的生产方法reproduce会根据实现类注解信息生成不同颜色的麻雀。昆明Java培训机构的老师编写一个客户端调用,代码如下:

1 public static void main(String[] args) {

2        Bird bird = BirdNest.Sparrow.reproduce();

3        Color color = bird.getColor();

4        System.out.println("Bird's color is :" + color);

5    }

现在问题是这段客户端程序会打印出什么来?因为采用了工厂方法模式,它最主要的问题就是bird变量到底采用了那个构造函数来生成,是无参构造函数还是有参构造?如果我们单独看子类Sparrow,它没有被添加任何注释,那工厂方法中的bd变量就应该是null了,应该调用的是无参构造。是不是如此呢?我们来看运行结果:“Bird‘s Color is White”;

白色?这是我们添加到父类Bird上的颜色,为什么?这是因为我们在注解上加了@Inherited注解,它表示的意思是我们只要把注解@Desc加到父类Bird上,它的所有子类都会从父类继承@Desc注解,不需要显示声明,这与Java的继承有点不同,若Sparrow类继承了Bird却不用显示声明,只要@Desc注解释可自动继承的即可。

采用@Inherited元注解有利有弊,利的地方是一个注解只要标注到父类,所有的子类都会自动具有父类相同的注解,整齐,统一而且便于管理,弊的地方是单单阅读子类代码,我们无从知道为何逻辑会被改变,因为子类没有显示标注该注解。总体上来说,使用@Inherited元注解弊大于利,特别是一个类的继承层次较深时,如果注解较多,则很难判断出那个注解对子类产生了逻辑劫持。

上一篇:Java程序建议:枚举项的数量限制在64个以内
下一篇:java程序建议:枚举和注解结合

达内java程序员掌握技术就掌握铁饭碗

Java面试3大经验,线程间协作原理

iPhone摄像头发展史一步一个脚印

腾讯游戏Switch独立销量领先——昆明达内

选择城市和中心
贵州省

广西省

海南省