zoukankan      html  css  js  c++  java
  • 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+"){
    
    }");
            }
    
    
        }
    }
    通过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+ "){
    
    }" );
            }
        }
    }
    通过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
    古人学问无遗力,少壮工夫老始成。 纸上得来终觉浅,绝知此事要躬行。
  • 相关阅读:
    django4-模板进阶
    django3-视图函数进阶
    django1-web开发基础知识
    django2-登录与出版社
    django3-路由系统进阶
    web前端-bootstrap
    Java发送邮件--web.xml配置,Java代码配置
    yii框架美化访问路径,去掉index.php/?r=部分
    JAVA集合框架的特点及实现原理简介
    详解:Java字符串类型"switch"的底层原理
  • 原文地址:https://www.cnblogs.com/wf-zhang/p/14155901.html
Copyright © 2011-2022 走看看