Java筑基35-反射(框架底层,必须掌握)

目录

一、反射机制 

1.一个需求引出反射

2.反射原理图

3.反射相关类

4. 反射调用优化

二、Class类

1.Class类分析

2.Class常用方法

3.获取class对象的各种方式(六种)

4.哪些类型有Class对象

三、类加载

1.动态加载和静态加载

2.类加载流程

3.类加载的五个阶段

四、反射获取类的结构信息

1.获取类结构信息

2.通过反射创建对象

3.通过反射操作属性

4.通过反射操作方法

5.案例练习

1)操作属性

2)利用反射创建文件


一、反射机制 

1.一个需求引出反射

re.properties

classfullpath=com.feiyang.basic17_reflect.Cat
--method=hi
method=run

package com.feiyang.basic17_reflect;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class Cat {
    private String name="招财猫";
    public void hi(){
        System.out.println("hi " + name);
    }

    public void run(){
        System.out.println("run " + name);
    }
}
package com.feiyang.basic17_reflect;

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class ReflectionQuestion {

    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //需求:根据配置文件指定信息,创建Cat对象并调用方法

        //传统实现方式:
        /*Cat c = new Cat();
        c.hi();*/

        //明白反射

        //1.读去配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\re.properties"));
        String classfullpath = properties.get("classfullpath").toString();
        String method = properties.get("method").toString();
        System.out.println("classfullpath=" + classfullpath);
        System.out.println("method=" + method);

        //创建对象,传统方法行不通 =》 反射机制
        Class aClass = Class.forName(classfullpath); //获取Class对象
        Object o = aClass.newInstance();  //实例化对象

        Method method1 = aClass.getMethod(method);  //通过Class对象获取方法(方法对象)
        method1.invoke(o);  //调用方法

    }
}

执行结果:

classfullpath=com.feiyang.basic17_reflect.Cat

method=run

run 招财猫

2.反射原理图

反射机制原理图:

3.反射相关类

package com.feiyang.basic17_reflect;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class Reflection01 {
    public static void main(String[] args) throws Exception {
        //1.读去配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\re.properties"));
        String classfullpath = properties.get("classfullpath").toString();
        String method = properties.get("method").toString();

        Class c = Class.forName(classfullpath); //获取Class对象
        Object o = c.newInstance();  //实例化对象


        //获取构造器(无参)
        Constructor constructor = c.getConstructor();
        System.out.println(constructor);

        //获取构造器(有参)
        Constructor constructor1 = c.getConstructor(String.class, int.class);
        System.out.println(constructor1);

        //获取属性
        Field age = c.getField("age");
        System.out.println(age.get(o));

        //获取方法
        Method method1 = c.getMethod(method);
        method1.invoke(o);  //调用方法

    }
}

执行结果:

public com.feiyang.basic17_reflect.Cat()

public com.feiyang.basic17_reflect.Cat(java.lang.String,int)

10

run 招财猫

4. 反射调用优化

代码示例:

re.properties

classfullpath=com.feiyang.basic17_reflect.Cat
method=hi

package com.feiyang.basic17_reflect;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class Cat {
    private String name="招财猫";
    public int age = 10;

    public Cat(){

    }

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void hi(){
        //System.out.println("hi " + name);
    }

    public void run(){
        //System.out.println("run " + name);
    }
}

package com.feiyang.basic17_reflect;

import java.io.FileInputStream;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class Reflection02 {
    public static void main(String[] args) throws Exception {
        m1();
        m2();
        m3();

    }

    //传统方法调用
    public static void m1(){
        Cat cat = new Cat();
        long l = System.currentTimeMillis();
        for (int i = 0; i < 900000000; i++) {
            cat.hi();
        }
        long l1 = System.currentTimeMillis();
        System.out.println(l1-l);

    }


    //反射方式调用
    public static void m2() throws Exception {
        //1.读去配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\re.properties"));
        String classfullpath = properties.get("classfullpath").toString();
        String method = properties.get("method").toString();

        Class c = Class.forName(classfullpath); //获取Class对象
        Object o = c.newInstance();  //实例化对象

        //获取方法
        Method method1 = c.getMethod(method);
        long l = System.currentTimeMillis();
        for (int i = 0; i < 900000000; i++) {
            method1.invoke(o);  //调用方法
        }
        long l1 = System.currentTimeMillis();
        System.out.println(l1-l);
    }

    //反射调用优化(禁止安全检查)

    public static void m3() throws Exception {
        //1.读去配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\re.properties"));
        String classfullpath = properties.get("classfullpath").toString();
        String method = properties.get("method").toString();

        Class c = Class.forName(classfullpath); //获取Class对象
        Object o = c.newInstance();  //实例化对象

        //获取方法
        Method method1 = c.getMethod(method);
        method1.setAccessible(false);
        long l = System.currentTimeMillis();
        for (int i = 0; i < 900000000; i++) {
            method1.invoke(o);  //调用方法
        }
        long l1 = System.currentTimeMillis();
        System.out.println(l1-l);
    }

}

Relection02执行结果:

0

1954

1838

二、Class类

1.Class类分析

先看下Class类的类图:

可以看到Class类和别的类是一样的,同样继承了Object类,只是他的使用方法和所完成的功能有些特殊性,仅此而已(所以啦,不要觉得他很神秘呦)

示例:

package com.feiyang.basic17_reflect;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:  Class类分析
 */
public class Class01 {
    public static void main(String[] args) throws ClassNotFoundException {

        //传统方法
        /**
         * debug发现:
         *
         * ClassLoader类的方法,加载
         * public Class<?> loadClass(String name) throws ClassNotFoundException {
         *         return loadClass(name, false);
         *     }
         */
        Cat cat = new Cat();

        //第2点:Class类对象不是new出来的,而是系统创建的
        /**
         * debug发现:
         *
         * 同样是ClassLoader类的方法,加载
         * public Class<?> loadClass(String name) throws ClassNotFoundException {
         *         return loadClass(name, false);
         *     }
         */
        Class c = Class.forName("com.feiyang.basic17_reflect.Cat");


        //第3点:对于某个类的Class类对象,在内存中只有一份,因为类只加载一次
        //此处要把上面的new 注释掉,否则,debug不到ClassLoader

    }
}

2.Class常用方法

package com.feiyang.basic17_reflect;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class Car {
    public String brand = "奔驰";
    public double price = 30.0;
    public String color = "灰色";

}
package com.feiyang.basic17_reflect;

import java.lang.reflect.Field;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class Class02 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //<?> 表示类型不确定
        //1 获取Car类对应的Class对象
        Class<?> cls = Class.forName("com.feiyang.basic17_reflect.Car");

        //2 输出cls
        System.out.println(cls);//显示cls对象,是哪个类的Class对象,class com.feiyang.basic17_reflect.Car
        System.out.println(cls.getClass());//显示cls运行类型,class java.lang.Class

        //3 得到包名
        System.out.println(cls.getPackage().getName());//com.feiyang.basic17_reflect

        //4 得到全类名
        System.out.println(cls.getName());//com.feiyang.basic17_reflect.Car

        //5 通过cls创建对象实例
        Car car = (Car)cls.newInstance();
        System.out.println(car);//com.feiyang.basic17_reflect.Car@610455d6

        //6 通过反射获取属性
        Field brand = cls.getField("brand");
        System.out.println(brand.get(car));//奔驰

        //7 通过反射给属性赋值
        brand.set(car,"宝马");
        System.out.println(brand.get(car));//宝马

        //8 得到所有属性
        Field[] fields = cls.getFields();
        for (Field f : fields) {
            System.out.println(f.getName());
        }
        /**
         * brand
         * price
         * color
         */

        for (Field f : fields) {
            System.out.println(f.get(car));
        }
        /**
         * 宝马
         * 30.0
         * 灰色
         */


    }
}

3.获取class对象的各种方式(六种)

package com.feiyang.basic17_reflect;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class GetClass_ {
    public static void main(String[] args) throws ClassNotFoundException {
        //1. Class.forName  通过读取配置文件
        String classPath = "com.feiyang.basic17_reflect.Car";
        Class<?> cls1 = Class.forName(classPath);
        System.out.println(cls1);  

        //2. 类名.class   应用场景:用于参数传递
        Class<Car> cls2 = Car.class;
        System.out.println(cls2);

        //3. 对象.getClass()  应用场景:有对象实例
        Car car = new Car();
        Class cls3 = car.getClass();
        System.out.println(cls3);

        //4. 通过类加载器来获取到类的class对象
        ClassLoader classLoader = car.getClass().getClassLoader();
        Class cls4 = classLoader.loadClass(classPath);
        System.out.println(cls4);

        //其实,上面的cls1、cls2、cls3、cls4
        System.out.println(cls1);
        System.out.println(cls2);
        System.out.println(cls3);
        System.out.println(cls4);//class com.feiyang.basic17_reflect.Car

        //5. 基本数据类型通过 .class获取Class对象
        Class<Integer> integerClass = int.class;
        Class<Character> characterClass = char.class;
        Class<Boolean> booleanClass = boolean.class;
        System.out.println(integerClass);//int

        //6. 基本数据类型对应的包装类可以通过.TYPE获取Class对象
        Class<Integer> type = Integer.TYPE;
        Class<Character> type1 = Character.TYPE;
        System.out.println(type);//int
        System.out.println(type1);//char

        System.out.println(integerClass.hashCode() == type.hashCode());//结果为true


    }
}

4.哪些类型有Class对象

package com.feiyang.basic17_reflect;

import java.io.Serializable;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class AllTypeClass {
    public static void main(String[] args) {
        Class<String> cls1 = String.class;
        Class<Serializable> cls2 = Serializable.class;
        Class<Integer[]> cls3 = Integer[].class;
        Class<float[][]> cls4 = float[][].class;
        Class<Deprecated> cls5 = Deprecated.class;
        Class<Thread.State> cls6 = Thread.State.class;
        Class<Long> cls7 = long.class;
        Class<Void> cls8 = void.class;
        Class<Class> cls9 = Class.class;

        System.out.println(cls1);
        System.out.println(cls2);
        System.out.println(cls3);
        System.out.println(cls4);
        System.out.println(cls5);
        System.out.println(cls6);
        System.out.println(cls7);
        System.out.println(cls8);
        System.out.println(cls9);


    }
}

打印输出:

class java.lang.String

interface java.io.Serializable

class [Ljava.lang.Integer;

class [[F

interface java.lang.Deprecated

class java.lang.Thread$State

long

void

class java.lang.Class

三、类加载

1.动态加载和静态加载

package com.feiyang.basic17_reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Scanner;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class classLoad_ {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您要查询的序号: ");
        String next = scanner.next();
        switch (next){
            case "1":
                Car car = new Car();//静态加载,编译期就会加载Car类,找不到会报错
                System.out.println(car.brand);
                break;
            case "2":
                Class<?> cls = Class.forName("com.feiyang.basic17_reflect.Person");//动态加载,运行时加载,只有进入该条件时才会加载,编译期即使没有Person类也不会报错
                Object o = cls.newInstance();
                Method say = cls.getMethod("say");
                say.invoke(o);
                break;
            default:
                System.out.println("输入有误!");
                break;
        }
    }
}

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

2.类加载流程

3.类加载的五个阶段

1)加载

2)连接

3)初始化

四、反射获取类的结构信息

1.获取类结构信息

package com.feiyang.basic17_reflect;

import org.junit.jupiter.api.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class ReflectionUtils {

    public static void main(String[] args) {

    }

    @Test
    public void api_03() throws ClassNotFoundException {
        Class<?> cls = Class.forName("com.feiyang.basic17_reflect.People");
        Method[] declaredMethods = cls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("获取本类中所有的方法:" + declaredMethod.getName()
            + "该方法的修饰符值:" + declaredMethod.getModifiers()
            + "该方法的返回值类型:" + declaredMethod.getReturnType());

            //输出当前方法的形参类型数组
            Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
            for (Class<?> parameterType : parameterTypes) {
                System.out.println("该方法的参数类型:" + parameterType.getName());
            }
        }
    }

    @Test
    public void api_02() throws ClassNotFoundException {
        Class<?> cls = Class.forName("com.feiyang.basic17_reflect.People");
        Field[] declaredFields = cls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("获取本类中所有的属性:" +declaredField.getName()
            + "该属性的修饰符值:" + declaredField.getModifiers()
            + "该属性的类型:" + declaredField.getType());
        }
    }

    @Test
    public void api_01() throws ClassNotFoundException {
        Class<?> cls = Class.forName("com.feiyang.basic17_reflect.People");
        System.out.println("获取全类名:" + cls.getName());

        System.out.println("==");
        System.out.println("获取简单类名:" +cls.getSimpleName());

        System.out.println("==");
        Field[] fields = cls.getFields();
        for (Field field : fields) {
            System.out.println("获取所有public修饰的属性,包括本类以及父类:" +field.getName());
        }

        System.out.println("==");
        Field[] declaredFields = cls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("获取本类中所有的属性:" +declaredField.getName());
        }

        System.out.println("==");
        Method[] methods = cls.getMethods();
        for (Method method : methods) {
            System.out.println("获取所有public修饰的方法,包括本类以及父类:" + method.getName());
        }

        System.out.println("==");
        Method[] declaredMethods = cls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("获取本类中所有的方法:" + declaredMethod.getName());
        }

        System.out.println("==");
        Constructor<?>[] constructors = cls.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("获取所有public修饰的构造器,包括本类:" + constructor.getName());
        }

        System.out.println("==");
        Constructor<?>[] declaredConstructors = cls.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("获取本类中所有的构造器:" + declaredConstructor.getName());
        }

        System.out.println("==");
        Package aPackage = cls.getPackage();
        System.out.println("获取包信息:" + aPackage);

        System.out.println("==");
        Class<?> superclass = cls.getSuperclass();
        System.out.println("获取父类Class对象信息:" + superclass.getName());

        System.out.println("==");
        Class<?>[] interfaces = cls.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            System.out.println("获取接口信息:" + anInterface.getName());
        }

        System.out.println("==");
        Annotation[] annotations = cls.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println("获取注解信息:" + annotation);
        }

    }
}

interface IA{

}

@Deprecated
class People implements IA{
    public String name;
    protected int age;
    String address;
    private double sal;

    public People() {
    }

    public People(String name, int age, String address, double sal) {
        this.name = name;
        this.age = age;
        this.address = address;
        this.sal = sal;
    }

    public void m1(String a,int b){
        System.out.println("m1");
    }

    protected String m2(){
        System.out.println("m2");
        return null;
    }

    void m3(){
        System.out.println("m3");
    }

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

api_01()执行结果:

获取全类名:com.feiyang.basic17_reflect.People

==

获取简单类名:People

==

获取所有public修饰的属性,包括本类以及父类:name

==

获取本类中所有的属性:name

获取本类中所有的属性:age

获取本类中所有的属性:address

获取本类中所有的属性:sal

==

获取所有public修饰的方法,包括本类以及父类:m1

获取所有public修饰的方法,包括本类以及父类:wait

获取所有public修饰的方法,包括本类以及父类:wait

获取所有public修饰的方法,包括本类以及父类:wait

获取所有public修饰的方法,包括本类以及父类:equals

获取所有public修饰的方法,包括本类以及父类:toString

获取所有public修饰的方法,包括本类以及父类:hashCode

获取所有public修饰的方法,包括本类以及父类:getClass

获取所有public修饰的方法,包括本类以及父类:notify

获取所有public修饰的方法,包括本类以及父类:notifyAll

==

获取本类中所有的方法:m1

获取本类中所有的方法:m2

获取本类中所有的方法:m4

获取本类中所有的方法:m3

==

获取所有public修饰的构造器:com.feiyang.basic17_reflect.People

获取所有public修饰的构造器:com.feiyang.basic17_reflect.People

==

获取本类中所有的构造器:com.feiyang.basic17_reflect.People

获取本类中所有的构造器:com.feiyang.basic17_reflect.People

==

获取包信息:package com.feiyang.basic17_reflect

==

获取父类Class对象信息:java.lang.Object

==

获取接口信息:com.feiyang.basic17_reflect.IA

==

获取注解信息:@java.lang.Deprecated()

package com.feiyang.basic17_reflect;

import org.junit.jupiter.api.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class ReflectionUtils {

    public static void main(String[] args) {

    }

    @Test
    public void api_03() throws ClassNotFoundException {
        Class<?> cls = Class.forName("com.feiyang.basic17_reflect.People");
        Method[] declaredMethods = cls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("获取本类中所有的方法:" + declaredMethod.getName()
            + "该方法的修饰符值:" + declaredMethod.getModifiers()
            + "该方法的返回值类型:" + declaredMethod.getReturnType());

            //输出当前方法的形参类型数组
            Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
            for (Class<?> parameterType : parameterTypes) {
                System.out.println("该方法的参数类型:" + parameterType.getName());
            }
        }
    }

    @Test
    public void api_02() throws ClassNotFoundException {
        Class<?> cls = Class.forName("com.feiyang.basic17_reflect.People");
        Field[] declaredFields = cls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("获取本类中所有的属性:" +declaredField.getName()
            + "该属性的修饰符值:" + declaredField.getModifiers()
            + "该属性的类型:" + declaredField.getType());
        }
    }

    @Test
    public void api_01() throws ClassNotFoundException {
        Class<?> cls = Class.forName("com.feiyang.basic17_reflect.People");
        System.out.println("获取全类名:" + cls.getName());

        System.out.println("==");
        System.out.println("获取简单类名:" +cls.getSimpleName());

        System.out.println("==");
        Field[] fields = cls.getFields();
        for (Field field : fields) {
            System.out.println("获取所有public修饰的属性,包括本类以及父类:" +field.getName());
        }

        System.out.println("==");
        Field[] declaredFields = cls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("获取本类中所有的属性:" +declaredField.getName());
        }

        System.out.println("==");
        Method[] methods = cls.getMethods();
        for (Method method : methods) {
            System.out.println("获取所有public修饰的方法,包括本类以及父类:" + method.getName());
        }

        System.out.println("==");
        Method[] declaredMethods = cls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("获取本类中所有的方法:" + declaredMethod.getName());
        }

        System.out.println("==");
        Constructor<?>[] constructors = cls.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("获取所有public修饰的构造器,包括本类:" + constructor.getName());
        }

        System.out.println("==");
        Constructor<?>[] declaredConstructors = cls.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("获取本类中所有的构造器:" + declaredConstructor.getName());
        }

        System.out.println("==");
        Package aPackage = cls.getPackage();
        System.out.println("获取包信息:" + aPackage);

        System.out.println("==");
        Class<?> superclass = cls.getSuperclass();
        System.out.println("获取父类Class对象信息:" + superclass.getName());

        System.out.println("==");
        Class<?>[] interfaces = cls.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            System.out.println("获取接口信息:" + anInterface.getName());
        }

        System.out.println("==");
        Annotation[] annotations = cls.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println("获取注解信息:" + annotation);
        }

    }
}

interface IA{

}

@Deprecated
class People implements IA{
    public String name;
    protected int age;
    String address;
    private double sal;

    public People() {
    }

    public People(String name, int age, String address, double sal) {
        this.name = name;
        this.age = age;
        this.address = address;
        this.sal = sal;
    }

    public void m1(String a,int b){
        System.out.println("m1");
    }

    protected String m2(){
        System.out.println("m2");
        return null;
    }

    void m3(){
        System.out.println("m3");
    }

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

api_02()执行结果:

获取本类中所有的属性:name该属性的修饰符值:1该属性的类型:class java.lang.String

获取本类中所有的属性:age该属性的修饰符值:4该属性的类型:int

获取本类中所有的属性:address该属性的修饰符值:0该属性的类型:class java.lang.String

获取本类中所有的属性:sal该属性的修饰符值:2该属性的类型:double

package com.feiyang.basic17_reflect;

import org.junit.jupiter.api.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class ReflectionUtils {

    public static void main(String[] args) {

    }

    @Test
    public void api_03() throws ClassNotFoundException {
        Class<?> cls = Class.forName("com.feiyang.basic17_reflect.People");
        Method[] declaredMethods = cls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("获取本类中所有的方法:" + declaredMethod.getName()
            + "该方法的修饰符值:" + declaredMethod.getModifiers()
            + "该方法的返回值类型:" + declaredMethod.getReturnType());

            //输出当前方法的形参类型数组
            Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
            for (Class<?> parameterType : parameterTypes) {
                System.out.println("该方法的参数类型:" + parameterType.getName());
            }
        }
    }

    @Test
    public void api_02() throws ClassNotFoundException {
        Class<?> cls = Class.forName("com.feiyang.basic17_reflect.People");
        Field[] declaredFields = cls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("获取本类中所有的属性:" +declaredField.getName()
            + "该属性的修饰符值:" + declaredField.getModifiers()
            + "该属性的类型:" + declaredField.getType());
        }
    }

    @Test
    public void api_01() throws ClassNotFoundException {
        Class<?> cls = Class.forName("com.feiyang.basic17_reflect.People");
        System.out.println("获取全类名:" + cls.getName());

        System.out.println("==");
        System.out.println("获取简单类名:" +cls.getSimpleName());

        System.out.println("==");
        Field[] fields = cls.getFields();
        for (Field field : fields) {
            System.out.println("获取所有public修饰的属性,包括本类以及父类:" +field.getName());
        }

        System.out.println("==");
        Field[] declaredFields = cls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("获取本类中所有的属性:" +declaredField.getName());
        }

        System.out.println("==");
        Method[] methods = cls.getMethods();
        for (Method method : methods) {
            System.out.println("获取所有public修饰的方法,包括本类以及父类:" + method.getName());
        }

        System.out.println("==");
        Method[] declaredMethods = cls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("获取本类中所有的方法:" + declaredMethod.getName());
        }

        System.out.println("==");
        Constructor<?>[] constructors = cls.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("获取所有public修饰的构造器,包括本类:" + constructor.getName());
        }

        System.out.println("==");
        Constructor<?>[] declaredConstructors = cls.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("获取本类中所有的构造器:" + declaredConstructor.getName());
        }

        System.out.println("==");
        Package aPackage = cls.getPackage();
        System.out.println("获取包信息:" + aPackage);

        System.out.println("==");
        Class<?> superclass = cls.getSuperclass();
        System.out.println("获取父类Class对象信息:" + superclass.getName());

        System.out.println("==");
        Class<?>[] interfaces = cls.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            System.out.println("获取接口信息:" + anInterface.getName());
        }

        System.out.println("==");
        Annotation[] annotations = cls.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println("获取注解信息:" + annotation);
        }

    }
}

interface IA{

}

@Deprecated
class People implements IA{
    public String name;
    protected int age;
    String address;
    private double sal;

    public People() {
    }

    public People(String name, int age, String address, double sal) {
        this.name = name;
        this.age = age;
        this.address = address;
        this.sal = sal;
    }

    public void m1(String a,int b){
        System.out.println("m1");
    }

    protected String m2(){
        System.out.println("m2");
        return null;
    }

    void m3(){
        System.out.println("m3");
    }

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

api_03()执行结果:

获取本类中所有的方法:m1该方法的修饰符值:1该方法的返回值类型:void

该方法的参数类型:java.lang.String

该方法的参数类型:int

获取本类中所有的方法:m2该方法的修饰符值:4该方法的返回值类型:class java.lang.String

获取本类中所有的方法:m4该方法的修饰符值:2该方法的返回值类型:void

获取本类中所有的方法:m3该方法的修饰符值:0该方法的返回值类型:void

package com.feiyang.basic17_reflect;

    import org.junit.jupiter.api.Test;

    import java.lang.annotation.Annotation;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;

    /**
     * @author:飞扬
     * @公众hao:程序员飞扬
     * @description:
     */
    public class ReflectionUtils {

        public static void main(String[] args) {

        }

        @Test
        public void api_04() throws ClassNotFoundException {
            Class<?> cls = Class.forName("com.feiyang.basic17_reflect.People");
            Constructor<?>[] declaredConstructors = cls.getDeclaredConstructors();
            for (Constructor<?> declaredConstructor : declaredConstructors) {
                System.out.println("获取本类中所有的构造器:" + declaredConstructor.getName()
                + "该构造器的修饰符值" + declaredConstructor.getModifiers());

                Class<?>[] parameterTypes = declaredConstructor.getParameterTypes();
                for (Class<?> parameterType : parameterTypes) {
                    System.out.println("该构造器的参数类型" + parameterType.getName());
                }
            }
        }

        @Test
        public void api_03() throws ClassNotFoundException {
            Class<?> cls = Class.forName("com.feiyang.basic17_reflect.People");
            Method[] declaredMethods = cls.getDeclaredMethods();
            for (Method declaredMethod : declaredMethods) {
                System.out.println("获取本类中所有的方法:" + declaredMethod.getName()
                + "该方法的修饰符值:" + declaredMethod.getModifiers()
                + "该方法的返回值类型:" + declaredMethod.getReturnType());

                //输出当前方法的形参类型数组
                Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
                for (Class<?> parameterType : parameterTypes) {
                    System.out.println("该方法的参数类型:" + parameterType.getName());
                }
            }
        }

        @Test
        public void api_02() throws ClassNotFoundException {
            Class<?> cls = Class.forName("com.feiyang.basic17_reflect.People");
            Field[] declaredFields = cls.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                System.out.println("获取本类中所有的属性:" +declaredField.getName()
                + "该属性的修饰符值:" + declaredField.getModifiers()
                + "该属性的类型:" + declaredField.getType());
            }
        }

        @Test
        public void api_01() throws ClassNotFoundException {
            Class<?> cls = Class.forName("com.feiyang.basic17_reflect.People");
            System.out.println("获取全类名:" + cls.getName());

            System.out.println("==");
            System.out.println("获取简单类名:" +cls.getSimpleName());

            System.out.println("==");
            Field[] fields = cls.getFields();
            for (Field field : fields) {
                System.out.println("获取所有public修饰的属性,包括本类以及父类:" +field.getName());
            }

            System.out.println("==");
            Field[] declaredFields = cls.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                System.out.println("获取本类中所有的属性:" +declaredField.getName());
            }

            System.out.println("==");
            Method[] methods = cls.getMethods();
            for (Method method : methods) {
                System.out.println("获取所有public修饰的方法,包括本类以及父类:" + method.getName());
            }

            System.out.println("==");
            Method[] declaredMethods = cls.getDeclaredMethods();
            for (Method declaredMethod : declaredMethods) {
                System.out.println("获取本类中所有的方法:" + declaredMethod.getName());
            }

            System.out.println("==");
            Constructor<?>[] constructors = cls.getConstructors();
            for (Constructor<?> constructor : constructors) {
                System.out.println("获取所有public修饰的构造器,包括本类:" + constructor.getName());
            }

            System.out.println("==");
            Constructor<?>[] declaredConstructors = cls.getDeclaredConstructors();
            for (Constructor<?> declaredConstructor : declaredConstructors) {
                System.out.println("获取本类中所有的构造器:" + declaredConstructor.getName());
            }

            System.out.println("==");
            Package aPackage = cls.getPackage();
            System.out.println("获取包信息:" + aPackage);

            System.out.println("==");
            Class<?> superclass = cls.getSuperclass();
            System.out.println("获取父类Class对象信息:" + superclass.getName());

            System.out.println("==");
            Class<?>[] interfaces = cls.getInterfaces();
            for (Class<?> anInterface : interfaces) {
                System.out.println("获取接口信息:" + anInterface.getName());
            }

            System.out.println("==");
            Annotation[] annotations = cls.getAnnotations();
            for (Annotation annotation : annotations) {
                System.out.println("获取注解信息:" + annotation);
            }

        }
    }

    interface IA{

    }

    @Deprecated
    class People implements IA{
        public String name;
        protected int age;
        String address;
        private double sal;

        public People() {
        }

        public People(String name, int age, String address, double sal) {
            this.name = name;
            this.age = age;
            this.address = address;
            this.sal = sal;
        }

        public void m1(String a,int b){
            System.out.println("m1");
        }

        protected String m2(){
            System.out.println("m2");
            return null;
        }

        void m3(){
            System.out.println("m3");
        }

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

api_04()执行结果:

获取本类中所有的构造器:com.feiyang.basic17_reflect.People该构造器的修饰符值1

获取本类中所有的构造器:com.feiyang.basic17_reflect.People该构造器的修饰符值1

该构造器的参数类型java.lang.String

该构造器的参数类型int

该构造器的参数类型java.lang.String

该构造器的参数类型double

2.通过反射创建对象

package com.feiyang.basic17_reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class ReflecCreateInstance {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class<?> cls = Class.forName("com.feiyang.basic17_reflect.User");

        //调用类中public修饰的无参构造器
        Object o = cls.newInstance();
        System.out.println(o);

        //调用类中指定构造器(公有的)
        Constructor<?> declaredConstructor = cls.getConstructor(String.class);
        Object o1 = declaredConstructor.newInstance("feiyang");
        System.out.println(o1);

        //调用类中指定构造器(含私有的)
        Constructor<?> declaredConstructor1 = cls.getDeclaredConstructor(int.class, String.class);
        declaredConstructor1.setAccessible(true);//设置私有属性可访问
        Object feiyang = declaredConstructor1.newInstance(18, "feiyang");
        System.out.println(feiyang);

    }
}
class User{
    private int age;
    private String name;

    public User() {
    }

    public User(String name) {
        this.name = name;
    }

    private User(int age, String name) {
        this.age = age;
        this.name = name;
    }

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

User{age=0, name='null'}

User{age=0, name='feiyang'}

User{age=18, name='feiyang'}

3.通过反射操作属性

package com.feiyang.basic17_reflect;

import java.lang.reflect.Field;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class ReflectAccessProperty {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException {
        Class<?> cls = Class.forName("com.feiyang.basic17_reflect.Student");
        Object o = cls.newInstance();
        System.out.println(o.getClass());

        //使用反射来操作属性(公有属性)
        Field name = cls.getField("name");
        name.set(o,"张三丰");
        System.out.println(o);
        System.out.println(name.get(o));

        //使用反射来操作属性(私有属性)
        Field age = cls.getDeclaredField("age");
        age.setAccessible(true);
        age.set(o,100);
        System.out.println(o);
        System.out.println(age.get(o));

    }
}

class Student {
    public String name;

    private static int age;

    public Student() {
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }
}

执行结果:

class com.feiyang.basic17_reflect.Student

Student{name='张三丰'}

张三丰

Student{name='张三丰'}

100

4.通过反射操作方法

package com.feiyang.basic17_reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class ReflectAccessMethod {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        // 得到Boss类对象的Class对象
        Class<?> cls = Class.forName("com.feiyang.basic17_reflect.Boss");
        Object o = cls.newInstance();

        //得到hi方法对象(公有方法)
        Method hi = cls.getMethod("hi", String.class);
        hi.invoke(o, "我是xxx");

        //得到say方法(私有方法)
        Method say = cls.getDeclaredMethod("say", int.class, String.class, char.class);
        say.setAccessible(true);
        System.out.println(say.invoke(o, 100, "张三丰", '男'));

        //在反射中,方法如果有返回值统一返回Object,但是他的运行时类型和方法定义的返回类型一致
        Object retVal = say.invoke(o,25, "周芷若", '女');
        System.out.println(retVal.getClass());
    }
}

class Boss{
    public int age;
    private static String name;

    public Boss() {
    }

    private static String say(int n,String s,char c){
        return n + " " + s + " " + c;
    }

    public void hi(String s){
        System.out.println("hi " + s);
    }
}

hi 我是xxx

100 张三丰 男

class java.lang.String

5.案例练习

1)操作属性

package com.feiyang.basic17_reflect;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class Homework01 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
        Class<?> cls = Class.forName("com.feiyang.basic17_reflect.PrivateTest");
        Object o = cls.newInstance();

        Field name = cls.getDeclaredField("name");

        name.setAccessible(true);
        name.set(o,"tom");
        
        Method getName = cls.getMethod("getName");
        System.out.println(getName.invoke(o));

    }
}

class PrivateTest{
    private String name = "hellokitty";
    public String getName(){
        return name;
    }
}

打印输出:

tom

2)利用反射创建文件

package com.feiyang.basic17_reflect;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author:飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class Homework02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<?> cls = Class.forName("java.io.File");

        //得到所有的构造器
        Constructor<?>[] constructors = cls.getDeclaredConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("File构造器=" + constructor);
        }

        //指定得到public java.io.File(java.lang.String)
        Constructor<?> declaredConstructor = cls.getDeclaredConstructor(String.class);
        String filePath = "d:\\mynew.txt";
        Object file = declaredConstructor.newInstance(filePath);

        //得到createNewFile()方法对象
        Method createNewFile = cls.getDeclaredMethod("createNewFile");
        createNewFile.invoke(file);//创建文件,调用的是createNewFile()
        
        System.out.println("File的运行类型=" + file.getClass());
        System.out.println("创建文件成功=" + filePath);


    }
}

执行结果:

File构造器=public java.io.File(java.lang.String,java.lang.String)

File构造器=public java.io.File(java.lang.String)

File构造器=private java.io.File(java.lang.String,java.io.File)

File构造器=public java.io.File(java.io.File,java.lang.String)

File构造器=public java.io.File(java.net.URI)

File构造器=private java.io.File(java.lang.String,int)

File的运行类型=class java.io.File

创建文件成功=d:\mynew.txt

猜你喜欢

转载自blog.csdn.net/lu_xin5056/article/details/127135671