java注解编程

内置注解 •
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());
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值