Java基础增强-反射机制

4 反射的具体体现
4.1 准备工作
1、新建@InheritedAnnotation注解

@Target({ElementType.FIELD, ElementType.TYPE, ElementType.CONSTRUCTOR})
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface InheritedAnnotation {
String value();
}
2、新建@MyAnnotation注解

@Target({ElementType.FIELD, ElementType.TYPE, ElementType.CONSTRUCTOR})
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value();
}
3、新建一个Person类

@InheritedAnnotation(“Inherited”)
public class Person {

private Integer id;

public Person() {
}

public void say() {
    System.out.println("Hello Person");
}

}
4、新建一个User类继承Person类

@MyAnnotation(“myAnnotation”)
public class User extends Person {

@MyAnnotation("name")
public String name;

@MyAnnotation("sex")
private String sex;

protected int age;

public User() {
}

@MyAnnotation("User(name, sex, age)")
public User(String name, String sex, int age) {
    this.name = name;
    this.sex = sex;
    this.age = age;
}

@MyAnnotation("name")
private User(String name) {
    this.name = name;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getSex() {
    return sex;
}

public void setSex(String sex) {
    this.sex = sex;
}

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}

@Override
public String toString() {
    return "User{" +
            "name='" + name + '\'' +
            ", sex='" + sex + '\'' +
            ", age=" + age +
            '}';
}

private void sayHello() {
    System.out.println("Hello World");
}

}
4.2 获取Class类的三种方式
/**
* 三种获取Class对象的方式
* @param obj
* @return
* @throws ClassNotFoundException
*/
public static Class getClazz(Object obj) throws ClassNotFoundException {
//第一种方式:通过对象的全路径名获取Class对象
Class clazz = Class.forName(“com.base.domain.User”);
System.out.println(“1、通过对象的路径获取Class对象:” + clazz);
//第二种方式:通过对象的getClass方法获取Class对象
Class clazz1 = obj.getClass();
System.out.println(“2、通过对象实例的getClass方法获取Class对象:” + clazz1);
//第三种方式:通过对象的.class方法获取Class对象
Class clazz2 = User.class;
System.out.println(“3、通过对象.class方法获取Class对象:” + clazz2);
return clazz;
}
执行:

public class ReflectTest {
public static void main(String[] args) throws Exception {
User user = new User();
Class clazz = ReflectUtils.getClazz(user);
}
}
执行结果:

1、通过对象的路径获取Class对象:class com.base.domain.User
2、通过对象实例的getClass方法获取Class对象:class com.base.domain.User
3、通过对象.class方法获取Class对象:class com.base.domain.User
4.3 获取类的所有属性
/**
* 获取类的所有属性
* @param clazz
* @throws NoSuchFieldException
*/
public static void getAllFields(Class clazz) throws NoSuchFieldException {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
System.out.println(“获取类中的所有属性:” + field);
}
Field field = clazz.getDeclaredField(“name”);
System.out.println(“通过属性名获取类的属性:” + field);
}
执行结果:

获取类中的所有属性:public java.lang.String com.base.domain.User.name
获取类中的所有属性:private java.lang.String com.base.domain.User.sex
获取类中的所有属性:protected int com.base.domain.User.age
通过属性名获取类的属性:public java.lang.String com.base.domain.User.name
4.4 获取类的公开属性
/**
* 获取类中的公开属性
* @param clazz
* @throws NoSuchFieldException
*/
public static void getPublicFields(Class clazz) throws NoSuchFieldException {
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(“获取类中的共开属性:” + field);
}

    //clazz.getField(String name)方式不能获取私有的属性,会抛出NoSuchFieldException异常
    Field field1 = clazz.getField("name");
    System.out.println("通过属性名获取类的公开属性:" + field1);
}

执行结果:

获取类中的共开属性:public java.lang.String com.base.domain.User.name
通过属性名获取类的公开属性:public java.lang.String com.base.domain.User.name
4.5 获取本类的所有方法
/**
* 获取本类中的所有方法
* @param clazz
*/
public static void getAllMethods(Class clazz) throws NoSuchMethodException {
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println(“获取本类的所有方法:” + method);
}

    Method method = clazz.getDeclaredMethod("setSex", String.class);
    System.out.println("通过方法名获取setSex方法" + method);
}

执行结果:

获取本类的所有方法:public java.lang.String com.base.domain.User.toString()
获取本类的所有方法:public java.lang.String com.base.domain.User.getName()
获取本类的所有方法:public void com.base.domain.User.setName(java.lang.String)
获取本类的所有方法:public java.lang.String com.base.domain.User.getSex()
获取本类的所有方法:public void com.base.domain.User.setSex(java.lang.String)
获取本类的所有方法:public int com.base.domain.User.getAge()
获取本类的所有方法:public void com.base.domain.User.setAge(int)
获取本类的所有方法:private void com.base.domain.User.sayHello()
通过方法名获取setSex方法public void com.base.domain.User.setSex(java.lang.String)
4.6 获取本类及父类的公开方法
/**
* 获取本类及父类的所有公开方法,私有方法不会被获取
* @param clazz
*/
public static void getPublicMethods(Class clazz) throws NoSuchMethodException {
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(“获取类的所有公开方法,包括父类的方法:” + method);
}

    Method method = clazz.getMethod("getSex");
    System.out.println("通过方法名获取getSex方法" + method);
}

执行结果:

获取类的所有公开方法,包括父类的方法:public java.lang.String com.base.domain.User.toString()
获取类的所有公开方法,包括父类的方法:public java.lang.String com.base.domain.User.getName()
获取类的所有公开方法,包括父类的方法:public void com.base.domain.User.setName(java.lang.String)
获取类的所有公开方法,包括父类的方法:public java.lang.String com.base.domain.User.getSex()
获取类的所有公开方法,包括父类的方法:public void com.base.domain.User.setSex(java.lang.String)
获取类的所有公开方法,包括父类的方法:public int com.base.domain.User.getAge()
获取类的所有公开方法,包括父类的方法:public void com.base.domain.User.setAge(int)
获取类的所有公开方法,包括父类的方法:public void com.base.domain.Person.say()
获取类的所有公开方法,包括父类的方法:public final void java.lang.Object.wait() throws java.lang.InterruptedException
获取类的所有公开方法,包括父类的方法:public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
获取类的所有公开方法,包括父类的方法:public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
获取类的所有公开方法,包括父类的方法:public boolean java.lang.Object.equals(java.lang.Object)
获取类的所有公开方法,包括父类的方法:public native int java.lang.Object.hashCode()
获取类的所有公开方法,包括父类的方法:public final native java.lang.Class java.lang.Object.getClass()
获取类的所有公开方法,包括父类的方法:public final native void java.lang.Object.notify()
获取类的所有公开方法,包括父类的方法:public final native void java.lang.Object.notifyAll()
通过方法名获取getSex方法public java.lang.String com.base.domain.User.getSex()
4.7 获取类的所有构造方法
**
* 获取类的所有构造方法
* @param clazz
*/
public static void getAllConstructors(Class clazz) throws NoSuchMethodException {
Constructor[] constructors = clazz.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(“获取类的所有构造方法:” + constructor);
}

    Constructor constructor = clazz.getDeclaredConstructor(String.class);
    System.out.println("通过参数个数及类型获取构造方法:" + constructor);
}

执行结果:

获取类的所有构造方法:private com.base.domain.User(java.lang.String)
获取类的所有构造方法:public com.base.domain.User(java.lang.String,java.lang.String,int)
获取类的所有构造方法:public com.base.domain.User()
通过参数个数及类型获取构造方法:private com.base.domain.User(java.lang.String)
4.8 获取类的公开构造方法
/**
* 获取类的公开构造方法
* @param clazz
*/
public static void getPublicConstructors(Class clazz) throws NoSuchMethodException {
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(“获取类的公开构造方法:” + constructor);
}
Constructor constructor = clazz.getConstructor(String.class, String.class, int.class);
System.out.println(“通过参数个数及类型获取公开的构造方法:” + constructor);
}
执行结果:

获取类的公开构造方法:public com.base.domain.User(java.lang.String,java.lang.String,int)
获取类的公开构造方法:public com.base.domain.User()
通过参数个数及类型获取公开的构造方法:public com.base.domain.User(java.lang.String,java.lang.String,int)
4.9 获取本类上的注解
/**
* 获取类上的注解
* @param clazz
*/
public static void getClassAnnotations(Class clazz) {
Annotation[] annotations = clazz.getDeclaredAnnotations();
for (Annotation annotation : annotations) {
System.out.println(“获取类上的注解” + annotation);
}

    Annotation annotation = clazz.getDeclaredAnnotation(MyAnnotation.class);
    System.out.println("通过注解类获取注解:" + annotation);
}

执行结果:

获取类上的注解@com.base.annotation.MyAnnotation(value=myAnnotation)
通过注解类获取注解:@com.base.annotation.MyAnnotation(value=myAnnotation)
4.10 获取本类及父类的注解
/**

  • 获取类上的注解,会将父类中用@Inherited修饰的注解获取到
  • @param clazz
    */
    public static void getAnnotations(Class clazz) {
    Annotation[] annotations = clazz.getAnnotations();
    for (Annotation annotation : annotations) {
    System.out.println(“获取父类中可继承的及本类中的类注解” + annotation);
    }
    Annotation annotation = clazz.getAnnotation(InheritedAnnotation.class);
    System.out.println(“通过注解类获取注解:” + annotation);
    }
    执行结果:

获取父类中可继承的及本类中的类注解@com.base.annotation.InheritedAnnotation(value=Inherited)
获取父类中可继承的及本类中的类注解@com.base.annotation.MyAnnotation(value=myAnnotation)
通过注解类获取注解:@com.base.annotation.InheritedAnnotation(value=Inherited)
4.11 通过反射实例化对象
/**
* 通过反射实例化对象
* @param clazz
* @return
* @throws Exception
*/
public static Object newInstanceObject(Class clazz) throws Exception {
User user = (User)clazz.newInstance();
System.out.println(“通过newInstance方式实例化对象:” + user.toString());

    Constructor constructor = clazz.getDeclaredConstructor(String.class, String.class, int.class);
    user = (User) constructor.newInstance("张三", "男", 18);
    System.out.println("通过公开的构造方法方式实例化对象:" + user.toString());

    constructor = clazz.getDeclaredConstructor(String.class);
    constructor.setAccessible(true);//访问私有的方法及属性需要将Accessible设置为true
    user = (User) constructor.newInstance("李四");
    System.out.println("通过私有的构造方法方式实例化对象:" + user.toString());

    return user;
}

执行结果:

通过newInstance方式实例化对象:User{name=‘null’, sex=‘null’, age=0}
通过公开的构造方法方式实例化对象:User{name=‘张三’, sex=‘男’, age=18}
通过私有的构造方法方式实例化对象:User{name=‘李四’, sex=‘null’, age=0}
4.12 通过反射调用方法
/**
* 通过反射调用方法
* @param clazz
* @throws Exception
*/
public static void invokeMethod(Class clazz) throws Exception {
Method method = clazz.getDeclaredMethod(“setAge”, int.class);
User user = (User) newInstanceObject(clazz);
method.invoke(user, 28);
System.out.println(“通过反射调用setAge方法:” + user.toString());
}
执行结果:

通过反射调用setAge方法:User{name=‘李四’, sex=‘null’, age=28}
4.13 通过反射修改属性
/**
* 通过反射修改属性值
* @param clazz
* @throws Exception
*/
public static void invokeUpdateField(Class clazz) throws Exception {
Field field = clazz.getDeclaredField(“sex”);
User user = (User) newInstanceObject(clazz);
field.setAccessible(true);//如果是公开的属性,则不需要setAccessible为true
field.set(user, “女”);
System.out.println(“通过反射修改对象的私有属性值:” + user.toString());
}
执行结果:

通过反射修改对象的私有属性值:User{name=‘李四’, sex=‘女’, age=0}
龙华大道1号http://www.kinghill.cn/LongHuaDaDao1Hao/index.html

猜你喜欢

转载自blog.csdn.net/weixin_45121123/article/details/105288808