Java深入学习27:Java反射

Java深入学习27:Java反射

Java深入学习27:Java反射

常用方法

 Java深入学习27:Java反射

代码示例(基础类在最后)

1- 获取Class类的方式

public class ClassGetTest {

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        String className = "reflect.Animals";
        //1- 调用运行时类本身的.class属性
        Class<Animals> animalsClass = Animals.class;
        System.out.println(animalsClass.newInstance() instanceof  Animals );//true

        //2- 通过Class的静态方法获取:体现反射的动态性
        Class<?> aClass = Class.forName(className);
        System.out.println(aClass.newInstance() instanceof  Animals );//true

        //3- 通过运行时类的对象获取
        Animals animals = new Animals();
        Class<? extends Animals> aClass1 = animals.getClass();
        System.out.println(aClass1.newInstance() instanceof  Animals );//true

        //4- 通过类的加载器
        ClassLoader classLoader = ClassGetTest.class.getClassLoader();
        Class<?> aClass2 = classLoader.loadClass(className);
        System.out.println(aClass2.newInstance() instanceof  Animals );//true
    }
}

2- 类相关的方法

public class ReflectClassTest {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        Class<Animals> animalsClass = Animals.class;
        Class<Bird> birdClass = Bird.class;

        //1- <U> Class<? extends U> asSubclass(Class<U> clazz)
        //Casts this  object to represent a subclass of the class represented by the specified class object.
        //把传递的类的对象转换成代表其子类的对象
        Class<? extends Animals> aClass = birdClass.asSubclass(Animals.class);
        aClass.newInstance().eat();//Bird eat insert

        //2- T cast(Object obj)
        //Casts an object to the class or interface represented  by this object.
        //把对象转换成代表类或是接口的对象()
        Bird aBird = new Bird();
        Animals birdCast1 = animalsClass.cast(aBird);
        Bird birdCast2 = birdClass.cast(aBird);

        //3- ClassLoader getClassLoader()
        //Returns the class loader for the class.
        //获得类的加载器
        ClassLoader classLoader = birdClass.getClassLoader();


        //5- Package getPackage()
        Package aPackage = animalsClass.getPackage();
        System.out.println(aPackage.getName());//reflect

        //6-Class<?>[] getInterfaces()
        Class<?>[] interfaces = animalsClass.getInterfaces();
        System.out.println(interfaces[0]);//interface reflect.AnimalAction

        //7-Class<? super T> getSuperclass()
        //获得当前类继承的父类的名字
        Class<? super Animals> superclass = animalsClass.getSuperclass();
        System.out.println(superclass.getName());//reflect.Creature

    }
}

3- 获得类中属性相关的方法

public class ReflectFieldTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class<Animals> animalsClass = Animals.class;
        System.out.println("------------------1-----------------");
        //1- 公有属性对象
        Field[] fields = animalsClass.getFields();
        Arrays.stream(fields).forEach(field-> System.out.println(field));
        System.out.println("------------------2-----------------");

        //2- 全部属性对象
        Field[] declaredFields = animalsClass.getDeclaredFields();
        Arrays.stream(declaredFields).forEach(declaredField-> System.out.println(declaredField));
        System.out.println("------------------3-----------------");
        //3-指定属性对象
        Field name = animalsClass.getDeclaredField("animalName");
        System.out.println(name);
    }
}

日志输出
------------------1-----------------
public reflect.Body reflect.Animals.body
------------------2-----------------
private java.lang.String reflect.Animals.animalName
public reflect.Body reflect.Animals.body
------------------3-----------------
private java.lang.String reflect.Animals.animalName

4- 获得类中注解相关的方法

public class ReflectAnnotationTest {

    //getDeclaredAnnotations得到的是当前成员所有的注释,不包括继承的。而getAnnotations得到的是包括继承的所有注释。
    public static void main(String[] args) {
        Class<Animals> animalsClass = Animals.class;
        System.out.println("--------------1----------------");

        Annotation[] annotations = animalsClass.getAnnotations();
        Arrays.stream(annotations).forEach(anno-> {
            System.out.println(anno);
            if(anno instanceof  AnnotationA){
                AnnotationA annotation = (AnnotationA) anno;
                System.out.println("description: " + annotation.description());

            }
            if(anno instanceof  AnnotationSup){
                AnnotationSup annotation = (AnnotationSup) anno;
                System.out.println("description: " + annotation.description());

            }
        });

        System.out.println("--------------2----------------");
        Annotation[] declaredAnnotations = animalsClass.getDeclaredAnnotations();
        Arrays.stream(declaredAnnotations).forEach(anno-> System.out.println(anno));
    }
}
日志输出
--------------1----------------
@reflect.AnnotationSup(description=this is AnnotationSup default description, name=creature)
description: this is AnnotationSup default description
@reflect.AnnotationA(description=this is AnnotationA default description, name=animal)
description: this is AnnotationA default description
--------------2----------------
@reflect.AnnotationA(description=this is AnnotationA default description, name=animal)

 5- 获得类中构造器相关的方法

public class ReflectConstructTest {
    public static void main(String[] args) throws NoSuchMethodException {
        Class<Animals> animalsClass = Animals.class;
        System.out.println("------------------------------1--------------------------------");
        //1-全部公有构造函数
        Constructor<?>[] constructors = animalsClass.getConstructors();
        Arrays.stream(constructors).forEach(con-> System.out.println(con));

        System.out.println("------------------------------2--------------------------------");
        //2- 全部构造函数(公有+私有)
        Constructor<?>[] declaredConstructors = animalsClass.getDeclaredConstructors();
        Arrays.stream(declaredConstructors).forEach(con-> System.out.println(con));

        System.out.println("------------------------------3--------------------------------");

        //3-获取制定参数类型的构造函数
        Constructor<Animals> constructor = animalsClass.getConstructor(String.class);
        System.out.println("constructor" + constructor);

    }
}
日志输出
-------------------1------------------
public void reflect.Animals.eat()
public void reflect.Animals.move()
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 java.lang.String java.lang.Object.toString()
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()
-------------------2------------------
private void reflect.Animals.sleep()
public void reflect.Animals.eat()
public void reflect.Animals.move()
-------------------3------------------
public void reflect.Animals.eat()

 6- 获得类中方法相关的方法

public class ReflectMethodTest {

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

        Class<Animals> animalsClass = Animals.class;
        System.out.println("-------------------1------------------");
        //1- 获取所有公有方法(包括父类的方法),不包括私有方法
        Method[] methods = animalsClass.getMethods();
        Arrays.stream(methods).forEach(method-> System.out.println(method));

        System.out.println("-------------------2------------------");

        //2- 获取当前全部方法(公有+私有),不包括父类方法
        Method[] declaredMethods = animalsClass.getDeclaredMethods();
        Arrays.stream(declaredMethods).forEach(method-> System.out.println(method));

        System.out.println("-------------------3------------------");

        //3- 获取指定方法
        Method sleep = animalsClass.getMethod("eat");
        System.out.println(sleep);

    }
}
日志方法
-------------------1------------------
public void reflect.Animals.eat()
public void reflect.Animals.move()
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 java.lang.String java.lang.Object.toString()
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()
-------------------2------------------
private void reflect.Animals.sleep()
public void reflect.Animals.eat()
public void reflect.Animals.move()
-------------------3------------------
public void reflect.Animals.eat()

7- Filed类相关方法

public class FieldTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
        Class<Animals> animalsClass = Animals.class;
        System.out.println("-----------------1----------------");

        //1- 获取全部公有对象
        Field[] fields = animalsClass.getFields();
        Arrays.stream(fields).forEach(field-> System.out.println(field));

        System.out.println("-----------------2----------------");

        //2- 获取全部对象(公有+私有)
        Field[] declaredFields = animalsClass.getDeclaredFields();
        Arrays.stream(declaredFields).forEach(declaredField-> System.out.println(declaredField));

        System.out.println("-----------------3----------------");

        //3-获取指定成员变量,并获取变量类型和名称
        Animals animals = animalsClass.newInstance();
        //3-1- 获取指定成员变量
        Field animalName = animalsClass.getDeclaredField("animalName");
        System.out.println(animalName);
        System.out.println(animalName.getType());
        //3-2- 获取指定成员变量的名称
        System.out.println(animalName.getName());
        //3-3- 设置指定成员变量的操作权限
        animalName.setAccessible(true);
        //3-4- 设置指定成员变量的值
        animalName.set(animals, "myCuteAnimal");
        //3-5- 获取指定成员变量的值
        System.out.println(animalName.get(animals));
        
        System.out.println("-----------------4----------------");

        //4- 获取父类的全部成员变量
        Class<? super Animals> superclass = animalsClass.getSuperclass();
        Field[] declaredFieldsSupers = superclass.getDeclaredFields();
        Arrays.stream(declaredFieldsSupers).forEach(declaredFieldsSuper-> System.out.println(declaredFieldsSuper));
    }
}
日志输出
-----------------1----------------
public reflect.Body reflect.Animals.body
-----------------2----------------
private java.lang.String reflect.Animals.animalName
public reflect.Body reflect.Animals.body
-----------------3----------------
private java.lang.String reflect.Animals.animalName
class java.lang.String
animalName
myCuteAnimal
-----------------4----------------
private java.lang.String reflect.Creature.creatureName

8- Method类相关方法

public class MethodTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class<Animals> animalsClass = Animals.class;
        Method[] declaredMethods = animalsClass.getDeclaredMethods();
        Arrays.stream(declaredMethods).forEach(declaredMethod-> {
            System.out.println(declaredMethod);
            try {
                //1- void setAccessible(boolean flag)
                //Set the accessible flag for this object to the indicated boolean value.
                //这是方法是可以使用的,对于被private修士的方法,如果accessible=false;则调用invoke()方法会报IllegalAccessException
                declaredMethod.setAccessible(true);
                //2- Object invoke(Object obj, Object... args)
                //执行当前方法
                declaredMethod.invoke(animalsClass.newInstance());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }
}
日志输出
private void reflect.Animals.sleep()
animal sleep...
public void reflect.Animals.move()
Animals move...
public void reflect.Animals.eat()
Animals eat...

9- Constructor类相关方法

public class ConstructTest {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        Class<Animals> animalsClass = Animals.class;
        System.out.println("------------------------------1--------------------------------");

        //1-获取制定参数类型的构造函数
        Constructor<Animals> constructor = animalsClass.getConstructor(String.class);
        System.out.println("constructor" + constructor);//constructorpublic reflect.Animals(java.lang.String)
        //2- 根据有参构造函数实例化一个对象(传入具体的参数值)
        Animals cuteAnimal = constructor.newInstance("myCuteAnimal");
        //3- 通过field获取指定成员变量的值
        Field animalName = cuteAnimal.getClass().getDeclaredField("animalName");
        animalName.setAccessible(true);
        System.out.println(animalName.get(cuteAnimal));//myCuteAnimal
    }
}

10-基础类

@AnnotationA(name="animal")
public class Animals extends  Creature implements AnimalAction{
    private String animalName;
    public Body body;
    public Animals() {
    }
    private Animals(Body body) {
        this.body = body;
    }
    public Animals(String animalName) {
        this.animalName = animalName;
    }

    public Animals(String animalName, Body body) {
        this.animalName = animalName;
        this.body = body;
    }
    @Override
    public void eat() {
        System.out.println("Animals eat...");
    }

    @Override
    public void move() {
        System.out.println("Animals move...");
    }

    private void sleep(){
        System.out.println("animal sleep...");
    }
}

@Target(ElementType.TYPE)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationA {

    String name();
    String description() default "this is AnnotationA default description";
}

@Target(ElementType.TYPE)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface AnnotationSup {

    String name();
    String description() default "this is AnnotationSup default description";
}

@AnnotationSup(name="creature")
public class Creature {

    private String creatureName;

    public void creatureMethod(){

    }
}

class Bird extends  Animals{
    private int legNum;

    public Bird() {
    }

    @Override
    public void eat() {
        System.out.println("Bird eat insert");
    }

}
interface AnimalAction{ void eat(); void move(); } class Body{ }

END