您的位置:首页 > 编程语言 > Java开发

java注解编程

2014-08-31 21:36 316 查看
内置注解 •
Override –继承父类方法 且重写(覆盖)父类方法

表示当前方法覆盖父类的方法,可以保证编译时 •

候Override函数声明的正确性
只能用于方法 •

@Override

public void sayHello(){

System.out.println("老师好!");

}

Deprecated -表明方法已经过时

表示当前元素是不赞成使用的 •
可以作用于类、属性、方法 •

@Deprecated

class Person{

@Deprecated

public String name;

@Deprecated

public void doSteal(){ //这个方法是不赞成使用的

System.out.println("偷东西是不对的!");

}

}

SuppressWarnings –

关闭特定的警告信息,如:使用泛型的时候未指定类型 •
可以作用于一段代码

@SuppressWarnings("serial")

public class Test implements Serializable{

@SuppressWarnings("unchecked")

Set set = new HashSet();

@SuppressWarnings("unchecked")

public static void main(String[] args) {

@SuppressWarnings("unused")

List list = new ArrayList();

}

}

自定义注解

类似于新创建一个接口类文件,但为了区分,我们需要将它声 •

明为@interface。

说明:

注解中的每个方法实际上是声明了一个配置参数 –

方法的返回值要求是:基本类型、String、Class、枚 –

举、Annotation和它们组成的数组

另外,可用使用@Target、@Retention等限制自定义注解 –

[<修饰符>] @interface <注解名>{

返回值 方法名称() [<default value>];

返回值 方法名称() [<default value>];

……

}

元注解

元注解是指注解的注解。包括 @Retention @Target @Document •

@Inherited四种。

@Retention: 定义注解的保留策略

@Target:定义注解的作用目标

@Document:说明该注解将被包含在javadoc中

@Inherited:说明子类可以继承父类中的该注解

在Java编译器编译时,会识别在源代码里添加的注解是否还会 •

保留,这就是RetentionPolicy。编译器的处理有三种策略:

@Retention(RetentionPolicy.RUNTIME) –

表示JVM运行时此注解存在 •

@Retention(RetentionPolicy.CLASS) –

表示仅在class文件中存在,程序运行无法读取 •

@Retention(RetentionPolicy.SOURCE) –

表示仅在源文件中存在,编译之后会丢失

限制注解的使用范围

@Target: 表示该注解可以用于什么地方。可用ElementType枚 •

举类型主要有:

TYPE : 类、接口或enum声明 –

FIELD: 域(属性)声明 –

METHOD: 方法声明 –

PARAMETER: 参数声明 –

CONSTRUCTOR: 构造方法声明 –

LOCAL_VARIABLE:局部变量声明 –

ANNOTATION_TYPE:注释类型声明 –

PACKAGE: 包声明 –

自定义注解-示例

/*

* 自定义注解

*/@

Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface MyAnnotation {

public enum FontColor {

BLUE, RED, GREEN

}i

nt id() default 100;

String info();

String[] names();

FontColor fontColor() default FontColor.RED;

}

public class MyAnnotationUsing {

@MyAnnotation(id = 1, info = "m1方法", names = { "zhangsan", "lisi" })

public void m1() {

}

@MyAnnotation(info = "m2方法", names = { "Tom", "Jerry" }, fontColor = FontColor.BLUE)

public void m2() {

}

}

/*

* 解析自定义注解

*/

public static void main(String[] args) throws ClassNotFoundException {

Class c = Class.forName("com.neuedu.MyAnnotationUsing");

Method[] methods = c.getDeclaredMethods();

for (Method method : methods) {

if (method.isAnnotationPresent(MyAnnotation.class)) {

MyAnnotation ann = method.getAnnotation(MyAnnotation.class);

System.out.println(method.getName() + ": " + ann.id() + ", "

+ ann.info() + ", " + Arrays.toString(ann.names()) + "," + ann.fontColor());

}

}

}

在程序中读取注解信息,需要用到反射。 •

在系统中用到注解权限时非常有用,可以精确控制权限的 –

粒度

注意:要想使用反射去读取注解,必须将Retention的值选 –

为RetentionPolicy.RUNTIME

Java反射机制(Reflection)

在运行状态中,对于任意一个类,都能够知道这个类的所 –

有属性和方法;对于任意一个对象,都能够调用它的任意

一个属性和方法。

这种动态获取类的信息及动态调用对象方法的功能称 –

为java语言的反射机制。

反射机制提供的功能:在运行时获得类中各成员并使用它们 •

在运行时判断任意一个对象所属的类; –

在运行时构造任意一个类的对象; –

在运行时判断任意一个类所具有的成员变量和方法; –

在运行时调用任意一个对象的方法; –

生成动态代理。 –

四个核心类

Java反射机制的实现要借助于以下4个类 •

Class:类对象 –

下面三个组件都是通过Class获取的 •

Constructor:类的构造器对象 –

Field:类的属性对象 –

Method:类的方法对象 –

Class的获取及常用方法

// 1、获取类的类对象

Class<?> c_1 = Class.forName("com.Student");

// 2、获取对象的类对象

Student student = new Student();

Class<?> c_2 = student.getClass();

// 3、获取int的类对象

Class<?> c_3 = int.class;

// 4、获取包装类的类对象

Class<?> c_4 = Integer.TYPE;

Class的获取及常用方法

常用方法 •

forName(String className):返回与带有给定字符串名的类或接 

口相关联的 Class 对象

getClassLoader() :返回该类的类加载器 

getDeclaredAnnotations() :返回直接存在于此元素上的所有注解 

getDeclaredConstructors() :返回类声明的所有构造方法 

getDeclaredFields():返回类声明的所有字段,包括公共、保 

护、默认(包)访问和私有字段,但不包括继承的字段

getDeclaredMethods() :返回类声明的所有方法,包括公共、保 

护、默认(包)访问和私有方法,但不包括继承的方法

getName() :以 String 的形式返回此 Class 对象所表示的实体( 

类、接口、数组类、基本类型或 void)名称

getPackage() : 获取此类的包 

Constructor的获取及常用方法

Class<?> c = Class.forName("com.neuedu.Student");

// 本数组作为待查询构造器的参数(按顺序)

Class<?>[] objs = new Class[] { String.class, double.class }; Constructor<?> c_1 = c.getConstructor(objs);

Constructor<?>[] c_2 = c.getConstructors();

Constructor<?> c_3 = c.getDeclaredConstructor(objs);

Constructor<?>[] c_4 = c.getDeclaredConstructors();

常用方法 •

getName():以字符串形式返回此构造方法的名称 

getModifiers():以整数形式返回此 Constructor 对象所表示构造方法的 

Java 语言修饰符

getDeclaredAnnotations():返回直接存在于此元素上的所有注释 

newInstance(Object... initargs) :使用此 Constructor 对象表示的构造方法 

来创建该构造方法的声明类的新实例

实现反射机制的步骤

实现反射机制有以下三步 •

1、获得你想操作的类的 java.lang.Class 对象 –

2、获得你想操作的类的组件 –

(Constructor、Field、Method)或组件列表

3、使用反射的API来操作这些组件

实现反射机制的步骤

// 1、先获取 Student 的类对象

Class<?> c = Class.forName("com.Student");

// 2、构造类的实例,可以使用private的构造器

Constructor<?> constructor = c.getDeclaredConstructor(double.class,

boolean.class); // 获取到private构造器

constructor.setAccessible(true);

Student student = (Student) constructor.newInstance(60, true); // score初始值设置为60

student.doStudy();

System.out.println();

// 3、调用方法,可以调用private的 doPlay()方法

// student.doPlay(); //直接使用,不能访问private方法

Method method = c.getDeclaredMethod("doPlay");

method.setAccessible(true); // 设置可以访问private方法

method.invoke(student);

Class[] cs = new Class[] { String.class, String.class };

Method method_2 = c.getDeclaredMethod("doEat", cs); // 调用有参有返回值的方法

String str = (String) method_2.invoke(student, "面包", "啤酒");

System.out.println(str);

System.out.println();

// 4、获取属性,可以获取private属性

// System.out.println(student.studyAtHome); //不能直接访问

Field field = c.getDeclaredField("studyAtHome");

field.setAccessible(true);

System.out

.println(field.getName() + " is " + field.getBoolean(student));

解析自定义注解

Class c = Class.forName("com.MyAnnotationUsing");

Method[] methods = c.getDeclaredMethods();

for (Method method : methods) {

if (method.isAnnotationPresent(MyAnnotation.class)) {

MyAnnotation ann = method.getAnnotation(MyAnnotation.class);

System.out.println(method.getName() + ": " + ann.id() + ", "

+ ann.info() + ", " + Arrays.toString(ann.names())

+ "," + ann.fontColor());

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java注解 注解编程