java-反射

反射

 

 

1.反射的概念

程序能够在运行时,观察、检测、修改自己运行时(Runtime)状态和行为的能力/特性.

2.java反射机制

在运行状态中,动态获取类的信息以及动态调用对象的方法的功能

 

正常方式  类---->对象 new对象---->类信息

反射方式  JavaAPI提供了Class类---->类信息

 

 

 

3.Java 反射机制的作用

在运行时判断任意一个对象所属的类

在运行时构造任意一个类的对象

在运行时判断任意一个类所具有的属性和方法

在运行时调用任意一个对象的方法

生成动态代理

 

4.反射常用的Java类 主要在java.lang.reflect包中

java.lang.Class<T>类可获取类和类的成员信息

java.lang.reflect.Constructor<T>类可调用类的构造方法

java.lang.reflect.Field类可访问类的属性 

java.lang.reflect.Method类可调用类的方法

 

5.Class类是Java反射机制的起源和入口

每个类都有自己向关的Class对象

提供了获取类信息的相关方法

Class类存放类的结构信息

类名

父类﹑接口

构造方法、方法、属性

注解 等

 

public class TestClass {
    public static void main(String[] args) {

        Class c1 = Map.class;
        Class c2 = List.class;
        Class c3 = Set.class;
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);


        Class C4 = Enum.class;
        Class C5 = Override.class;
        Class c6 = int.class;
        Class C7 = Integer.class;
        Class C8 = Integer.TYPE;
        System.out.println(C4);
        System.out.println(C5);
        System.out.println(c6);
        System.out.println(C7);
        System.out.println(C8);

        Class c9 = void.class;
        Class c10 = String[].class;
        Class c11 = double[][].class;
        System.out.println(c9);
        System.out.println(c10);
        System.out.println(c11);

        Class<Object> clz = Object.class;
        System.out.println(clz);

    }
}
所有类型都有对象的Class对象

 

6.创建Class实例的三种方式

    方式一 对象的getClass()方法

    Person p  =  New Person();

         Class cls =  Person.getClass();

    方式二 类的class属性

         Class cls =  Person.class;

    方式三  Class.forName("全类名");

        Class clazz = Class.forName("xxx.xxx. Person");

 

public class TestCtreateClass {

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

        //方式一 Class.forName
        //Class.forName("com.mysql.jdbc.Driver");
        Class<?> cls = Class.forName("cn.bdqn.pojo.Person");
        System.out.println(cls);
        System.out.println(cls.getName());


        //方式二 类的class属性
        Class<Person> personClass = Person.class;
        System.out.println(personClass);

        //方式三 对象的getClass()方法
        Person person = new Person();
        Class aClass = person.getClass();
        System.out.println(aClass);


        //一个类只有一个对应的Class对象 封装了整个类的结构
        System.out.println(cls.hashCode());
        System.out.println(personClass.hashCode());
        System.out.println(aClass.hashCode());


    }
}
创建Class实例

 

 

7.理解Class对象

 

 

 

 

 

 

 

 

8.通过Class获得类信息

 

 

 

public class TestClassInfo {
    public static void main(String[] args) {
        Class cls = Person.class;
        String name = cls.getName();
        System.out.println("类全名" + name);

        String pcSimpleName = cls.getSimpleName();
        System.out.println("类名" + pcSimpleName);

        Package pcPackage = cls.getPackage();
        System.out.println("类的包名" + pcPackage.getName());

        Class superclass = cls.getSuperclass();
        System.out.println("父类" + superclass.getName());

        boolean annotation = cls.isAnnotation();
        System.out.println("是否是注解" + annotation);

        boolean anInterface = cls.isInterface();
        System.out.println("是否是接口" + anInterface);

        boolean anEnum = cls.isEnum();
        System.out.println("是否是枚举" + anEnum);

        Class[] interfaces = cls.getInterfaces();
        for (Class c : interfaces){
            System.out.println("遍历接口名" + c.getName());
        }

        //类修饰符 1 public 2private 3 public private 4 protected
        int modifiers = cls.getModifiers();
        System.out.println("" + modifiers);
        String s = Modifier.toString(modifiers);
        System.out.println("" + s);

        System.out.println(Modifier.toString(2));
        System.out.println(Modifier.toString(3));
        System.out.println(Modifier.toString(4));

    }
}
通过Class获得类信息

 

 

9.通过Class 获得属性信息

 

 

 

 

public class TestField {
    public static void main(String[] args) throws NoSuchFieldException {
        //获得Class对象
        Class<Person> cls = Person.class;

        //getField 获得指定属性名并且public属性信息
        //属性修饰符  属性类型  属性名
        Field age = cls.getField("age");
        System.out.println("属性全部信息 = " + age);

        int modifiers = age.getModifiers();
        String s = Modifier.toString(modifiers);
        System.out.println("属性修饰符 = " + s);

        Class<?> ageType = age.getType();
        System.out.println("属性类型 = " + ageType);

        String name = age.getName();
        System.out.println("属性名 = " + name);

        System.out.println("===============================");
        //getFields 获得所有属性信息并且public
        for (Field f : cls.getFields()) {
            System.out.println("getFields= " + f.getName());
            System.out.println("getFields= " + f.getType().getName());
            System.out.println("getFields= " + Modifier.toString(f.getModifiers()));
        }

        System.out.println("===============================");
        //getDeclaredField 获得指定属性信息
        Field declaredField = cls.getDeclaredField("name");
        System.out.println("declaredField = " + declaredField);

        Field ageField = cls.getDeclaredField("age");
        System.out.println("ageField = " + ageField);

        System.out.println("===============================");
        //getDeclaredFields 获取所有属性
        for (Field field : cls.getDeclaredFields()) {
            System.out.println("getDeclaredFields遍历属性名 " + field.getName());
            System.out.println("getDeclaredFields遍历属性类型 " + field.getType().getName());
            System.out.println("getDeclaredFields遍历属性修饰符 " + Modifier.toString(field.getModifiers()));
        }


    }
}
通过Class获得属性信息

 

10.通过Class获得方法信息

 

 

 

public class TestMethod {
    public static void main(String[] args) throws NoSuchMethodException {
        //获取Class对象
        Class cls = Person.class;

        //1.getMethod 获得指定方法信息并且public
        //方法修饰符 返回的数据类型 方法名 参数
        Method age = cls.getMethod("setAge", int.class);
        System.out.println("方法全部信息 = " + age);

        int modifiers = age.getModifiers();
        System.out.println("方法修饰符 = " + Modifier.toString(modifiers));

        Class<?> returnType = age.getReturnType();
        System.out.println("返回数据类型 = " + returnType);

        String name = age.getName();
        System.out.println("方法名 = " + name);

        for (Class<?> ageParameterType : age.getParameterTypes()) {
            System.out.println("参数类型 = " + ageParameterType);
        }
        System.out.println("---------------------");

        //2.getMethods 获得所有方法信息并且public
        for (Method method : cls.getMethods()) {
            System.out.println("method = " + method);
        }

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

        //3.getDeclaredMethod 获得指定方法信息
        Method setAddress = cls.getDeclaredMethod("setAddress", String.class);
        System.out.println("方法全部信息 = " + setAddress);

        int modifiers2 = setAddress.getModifiers();
        System.out.println("方法修饰符 = " + Modifier.toString(modifiers2));

        Class<?> returnType2 = setAddress.getReturnType();
        System.out.println("返回数据类型 = " + returnType2);

        String name2 = setAddress.getName();
        System.out.println("方法名 = " + name2);

        for (Class<?> parameterType : setAddress.getParameterTypes()) {
            System.out.println("方法参数 = " + parameterType.getName());
        }

        System.out.println("---------------------");
        //4.getDeclaredMethods 获得所有方法信息
        //修饰符  返回值类型 方法名 (参数列表){}
        for (Method m : cls.getDeclaredMethods()) {
            //修饰符
            int mf = m.getModifiers();
            String s = Modifier.toString(mf);
            //返回值类型
            Class<?> mReturnType = m.getReturnType();
            //方法名
            String mName = m.getName();

            //参数
            Class<?>[] all = m.getParameterTypes();

            String paramStr = "";

            for (int i = 0; i <all.length ; i++) {
                paramStr +=all[i].getSimpleName() + " p"+i+",";
            }
            if (paramStr.length()>0){
                paramStr = paramStr.substring(0,paramStr.length()-1);
            }
            System.out.println(s + " " +mReturnType.getName()+" "+name + "("+paramStr+"){\n\n}");
        }


    }
}
通过Class获得方法信息

 

11.通过Class获得构造方法信息   

 

 

 

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

        //获取Class实例
        Class<Person> cls = Person.class;

        //1.getConstructor 指定参数的构造并且public
        Constructor<Person> con = cls.getConstructor(int.class);
        System.out.println("方法全部信息 = " + con);

        System.out.println("======================");
        //2.getConstructors 所有构造并且public
        Constructor<?>[] cons = cls.getConstructors();
        for (Constructor<?> constructor : cons) {
            System.out.println("constructor = " + constructor);
        }

        System.out.println("======================");
        //3.getDeclaredConstructor 获得构造
        Constructor<Person> declaredConstructor = cls.getDeclaredConstructor(String.class);
        System.out.println("declaredConstructor = " + declaredConstructor);

        System.out.println("======================");
        //4.getDeclaredConstructors 获得所有构造
        //权限修饰符 方法名 (参数列表...){}
        for (Constructor<?> constructor : cls.getDeclaredConstructors()) {
            //修饰符
            int modifiers = constructor.getModifiers();
            String s = Modifier.toString(modifiers);
            //方法名
            String name = constructor.getName();
            //参数
            Class<?>[] all = constructor.getParameterTypes();
            String paramStr = "";
            for (int i = 0; i < all.length; i++) {
                paramStr += all[i].getSimpleName() +" p"+i+ ",";
            }
            if (paramStr.length()>0){
                paramStr = paramStr.substring(0,paramStr.length()-1);
            }
            System.out.println(s+" " + name + "(" +paramStr+ "){\n\n}" );
        }
    }
}
通过Class获得构造方法信息

 

 

12 通过Class实例创建对象两种方式

方式一 Class.newInstance()方法

        Class<Person> cls = Person.class;

        Person p1 = cls.newInstance();

 

方式二 Class.getDeclaredConstructor() 构造方法 newInstance()

        Class<Person> cls2 = Person.class;

        Constructor<Person> constructor = cls2.getDeclaredConstructor();

        Person p2 = constructor.newInstance();

 

public class TestInstance {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //通过反射创建对象
        //方式一 Class对象 newInstance() 方法
        Class<Person> cls = Person.class;
        Person p1 = cls.newInstance();
        p1.setAge(18);
        System.out.println("p1.getAge() = " + p1.getAge());

        //方式二 Class对象 getDeclaredConstructor() 构造 newInstance()
        Class<Person> cls2 = Person.class;
        Constructor<Person> constructor = cls2.getDeclaredConstructor();
        Person p2 = constructor.newInstance();
        p2.setAge(18);
        System.out.println("p2.getAge() = " + p2.getAge());
    }
}
通过Class创建对象

 

13.反射机制 操作属性对象 属性赋值

 

 

public class TestOperateField {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
        //获得Class对象
        Class<Person> cls = Person.class;
        //获得Field属性对象
        Field address = cls.getDeclaredField("address");
        //反射创建对象
        Person person = cls.newInstance();
        //设置禁止检查
        address.setAccessible(true);
        //反射思想---------->属性对象赋值
        address.set(person,"加勒比海岸");
        Object o = address.get(person);
        System.out.println(o);
    }
}
反射机制 操作属性

 

 

14.反射机制 操作方法对象 传参

 

 

public class TestOperateMethod {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //获得Class对象
        Class<Person> cls = Person.class;
        //获得Method对象
        Method setName = cls.getDeclaredMethod("setName", String.class);
        //反射创建对象
        Person person = cls.newInstance();

        //禁止检查
        setName.setAccessible(true);
        //反射思想---------->方法对象
        setName.invoke(person,"张三");
        System.out.println("person.getName() = " + person.getName());

    }
}
反射机制 操作方法

 

15.案例

public class Computer {
    public void run(){
        System.out.println("Running...");
    }
    public void close(){
        System.out.println("Closed!");
    }
    //升级后的2代计算机:USB功能
    public void useUSB(USB usb){
        if(usb != null){//如果设备连接上,则开始使用设备功能
            usb.connection();
            usb.close();
        }
    }
}
Computer
public interface USB {
    public void connection();//设备连接
    public void close();//设备断开
}
USB
public class Keyboard implements USB {

    @Override
    public void connection() {
        System.out.println("键盘正在使用...");
    }

    @Override
    public void close() {
        System.out.println("键盘已断开连接!");
    }

}
Keyboard
public class Mouse implements USB {

    @Override
    public void connection() {
        System.out.println("鼠标正在使用...");
    }

    @Override
    public void close() {
        System.out.println("鼠标已断开连接!");
    }

}
Mouse
public class Test {
    public static void main(String[] args) throws Exception {
        Computer mc = new Computer();

        //我们只需要知道封装设备的类名即可
        String className = "cn.bdqn.demo.Keyboard";
        Class<?> c = Class.forName(className);
        Object obj = c.newInstance();

        USB usb = (USB)obj;
        mc.useUSB(usb);
    }
}
Test
public class Test2 {
    public static void main(String[] args) throws Exception {
        Computer mc = new Computer();
        
        //利用IO流,使用配置文件传入类名:
        File config = new File("E:/T123code/TestClass/src/cn/bdqn/demo/usb.config");
        FileInputStream fis = new FileInputStream(config);
        Properties prop = new Properties();
        prop.load(fis);
        String className = null;
        className = prop.getProperty("usb");
        
        
        Class<?> c = Class.forName(className);
        Object obj = c.newInstance();
        
        USB usb = (USB)obj;
        mc.useUSB(usb);
    }
}
Test2
usb=cn.bdqn.demo.Mouse
View Code

 

posted @ 2020-12-18 17:08  wf.zhang  阅读(276)  评论(0编辑  收藏  举报