1.什么是反射?
反射是一种机制,利用反射机制动态的实例化对象、读写属性、调用方法、构造函数。
2.如何得到类对象
一切反射相关的代码都从获得类对象开始
3种获取方式:
2.1 类名.class;
2.2 对象名.getClass();
2.3 Class.forName(全限定名/全路径名)
3.根据类得到类名(全限定名/全路径名)
1)cName.getName(); -->获取全限定名
2)cName.getSimpleName(); -->获取类名
3)cName.getPackage(); -->获取包名
4.根据类得到类的属性
Field field=cla.getField(“属性名”);
field.getName(); -->获取属性名
filed.getType(); -->获取属性类型
field.getModifiers(); -->获取属性访问修饰符
field.set(Object,Object); -->设置属性值,参数1:要设置属性所在对象;参数2:要设置的值;
field.get(Object); -->获取属性值,参数:要获取属性值的对象
field.getDeclaredField(“属性名”); -->获取单个属性(私有、公有、受保护、默认、静态)
field.getDeclaredFields(); -->获取所有属性(私有、公有、受保护、默认、静态)
5.根据类得到类的方法
//无参无返回、无参有参会、有参无返回、有参有返回
cla.getMethod(); -->获取单个公有方法
cla.getDeclaredMethod(); -->获取当个方法(包括私有、受保护、默认、公有)
cla.getMethods(); -->获取所有公有方法
cla.getDeclaredMethods(); -->获取所有的方法(包括私有、受保护、默认、公有)
6.根据类得到类的构造方法
cla.getConstrutor(); -->获取单个公有构造方法
cla.getDeclaredConstrutor(); -->获取单个构造方法(包括私有、受保护、默认、公有)
cla.getConstrutors(); -->获取所有的公有构造方法
cla.getDeclaredConstrutors(); -->获取所有的构造方法(包括私有、受保护、默认、公有)
7.根据类得到类的实现接口列表
Class[] interface=cla.getInterfaces(); -->获取类对象中所有实现接口列表
8.完成属性注解MyValue的编写与解析
9.完成组合注解MyValueLoad的编写
案例

建一个注解类
package com.zking.xmg;
import java.lang.annotation.*;
//其实就是标签
//每个注解上面可以添加元注解
@Documented //生成文档
@Target({ElementType.TYPE,ElementType.METHOD}) //注解可以写在什么地方 方法,属性,类,参数,本地参数
@Retention(RetentionPolicy.RUNTIME) //注解保留的时间 ,源码,字节码,运行时
@Inherited //这个注解可以被继承
//@Repeatable()
public @interface My01 {
//定义一些属性 这些属性其实是什么方法
//属性类型是否有限制
//所有的基本数据类型
//注解类型,类枚举(java中固定的变量)
季节 value();
enum 季节{
春,
夏,
秋,
咚;
}
}
建一个人类和测试类
package com.zking.xmg;
@My01(My01.季节.咚)
public class Person {
private String name;
private String age;
public Person() {
}
@My01(My01.季节.咚)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
package com.zking.xmg;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@My01(My01.季节.夏)
public class Test05 {
public static void main(String[] args) throws Exception{
//反射?java中的X光,可以看见类的结构,可以拿到类的东西
//一切反射相关的代码都从获得;类对象开始
Class<Person> p1 =Person.class;
Class<? extends Person> p2 = new Person().getClass();
Class<?> p3 = Class.forName("com.zking.xmg.Person");
//f1就是类中的名字属性
Person person =new Person();
Field f1 =p1.getDeclaredField("name");
//通过名字属性给person对象赋值
//属性在赋值需要操作权限
f1.setAccessible(true);
f1.set(person,"小黑子");
//拿属性的值
Object o =f1.get(person);
//那方法
Method m1 =p1.getDeclaredMethod("getName");
//调用方法
m1.invoke(person);
//拿方法
Method m2 =p1.getDeclaredMethod("setName", String.class);
//调用方法
m2.invoke(person,"小黑子");
//拿到方法
Method m3 = p1.getDeclaredMethod("getName");
//拿到方法上的注解
My01 a1 = m3.getDeclaredAnnotation(My01.class);
//可以拿值
System.out.println(a1.value());
//类上的注解
My01 a2 = Person.class.getDeclaredAnnotation(My01.class);
System.out.println(a2.value());
}
}
建一个food类和测试类
package coms.aoon;
@MyValueLoad(MyValueLoad.开关.开启)
public class food {
@Myvalue("food.name")
private String name;
private String type;
@Override
public String toString() {
return "food{" +
"name='" + name + '\'' +
", type='" + type + '\'' +
'}';
}
}
package coms.aoon;
public class test {
public static void main(String[] args) {
System.out.println(new Person());
System.out.println(new food());
}
}
建两个注解类
package coms.aoon;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//提供给我当前属性需要填充的值的名称
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Myvalue {
String value();
}
package coms.aoon;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//决定当前的MyValue注解是否起作用
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface MyValueLoad {
enum 开关{
开启,
关闭;
}
开关 value();
}
package coms.aoon;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Properties;
//注解读取
public class ValueHandler {
Properties properties=new Properties();
public ValueHandler(){
try{
//加载一个文件
properties.load(this.getClass().getResourceAsStream("value.properties"));
//拿到了类对象
Class<? extends ValueHandler> c1 =this.getClass();
//判断类的MyValueLoad注解是否开启
MyValueLoad mvl = c1.getDeclaredAnnotation(MyValueLoad.class);
if (mvl==null||mvl.value()== MyValueLoad.开关.关闭){
return;
}
//拿到类的属性
Field[] fs =c1.getDeclaredFields();
for (Field f : fs) {
//能不能拿到属性上的注解
Myvalue mv =f.getDeclaredAnnotation(Myvalue.class);
System.out.println(f.getName()+":"+mv);
//判断是否拿到注解
if(mv!=null){
//拿到注解的值
String name =mv.value();
//读取配置文件的值
Object obj =properties.get(name);
//将值该成属性
f.setAccessible(true);
f.set(this,obj);
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}