• 初学——java反射


    一、反射

      1.什么是反射

        反射是指在程序运行期间,能够观察和修改类或者类的对象的属性和行为的特性

      2.为什么用反射

        在java中有动态和静态的概念

        静态是指在java中所有的类都编写好编译通过运行

        动态是在在编写好类,编译运行中动态获取类的信息修改类的属性叫做反射.

        例如:在已经运行的大项目中需要修改代码,如果项目处于运营,停止项目会带来损失,所以用反射来达到修改代码的作用

      3.怎么用反射

        Java反射机制提供了以下的功能

        在运行时获取类的修饰符,包名,类名,实现的接口,继承的父类

        在运行时获取类的所有属性名,修饰符,属性类型

        在运行时获取所有方法,方法的返回值类型,方法名,方法参数数量,方法参数类型

        在运行时调用加载类的方法

      4.反射的练习

      创建父类Preson

    package dome;
    
    public class Preson {
        private int age;
        public String name;
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Preson() {
            System.out.println("Person的空构造");
            
            
        }
        public Preson(int age, String name) {
            this.age = age;
            this.name = name;
            System.out.println("Person的有参构造");
        }
        
        private void say() {
            System.out.println("Person的私有Say方法");
    
        }
        public void    talk() {
            System.out.println("Person的共有方法");
        } 
    }

    创建子类Student

    package dome;
    
    public final class Student extends Preson implements Runnable{
        public int stuid;
        private String sex;
        public String nameString;
        public int getStuid() {
            return stuid;
        }
        public void setStuid(int stuid) {
            this.stuid = stuid;
        }
        public String getSex() {
            return sex;
        }
        public void setSex(String sex) {
            this.sex = sex;
        }
        public String getNameString() {
            return nameString;
        }
        public void setNameString(String nameString) {
            this.nameString = nameString;
        }
        public Student(int stuid, String sex, String nameString) {
            super();
            this.stuid = stuid;
            this.sex = sex;
            this.nameString = nameString;
        }
        public Student() {
            super();
        }
        public Student(int age, String name) {
            super(age, name);
        }
        private String sleep(String name) {
            return "通过反射我被执行了";
        }
        @Override
        public void run() {
            // TODO Auto-generated method stub
            
        }
        @Override
        public String toString() {
            return "Student [stuid=" + stuid + ", sex=" + sex + ", nameString="
                    + nameString + "]";
        }
    
        
    }

    创建测试类

    package dome;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    import java.util.Arrays;
    
    public class Test {
        public static void main(String[] args) throws Exception {
            /*
             * 获取class类的对象
             */
            System.out.println("
    =========================通过反射获得类构造==================
    ");
            //方法一:
            System.out.println("***********************************************************");
            Student s1=new Student();
            Class c1=s1.getClass();
            System.out.println("方法一获取Student的构造");
            //方法二:
            System.out.println("**********************************************************");
            Class c2=Student.class;
            System.out.println("方法二获得的Student构造");
            //方法三:(最常用)
            System.out.println("*******************************");
            Class c3 = Class.forName("dome.Student");
            System.out.println("方法三(最常用)获得Student构造");
            /*
             * 获取类的构造函数
             */
            System.out.println("************获取构造函数***********************");
            System.out.println("**********************或取当前类所有构造方法*********");
            Constructor[] con1=c3.getConstructors();
            for (Constructor constructor : con1) {
                System.out.println(constructor);
            }
            //应用构造方法来创建对象的值
            System.out.println("通过构造方法我创建了一个对象:");
            Constructor con2=c3.getConstructor(int.class, String.class, String.class);
            Object object=con2.newInstance(13,"aa","bb");
            s1=(Student)object;
            System.out.println(s1);
            /*
             * 获取类的信息
             */
            System.out.println("
    =========================通过反射获得类的相关信息==================
    ");
            //获取类的名字
            System.out.println("*******************************************************************");
            System.out.println("通过getname()获取Student类的全称:"+c3.getName());
            System.out.println("通过getSimplename()获取Student类的简称:"+c3.getSimpleName());
            //获取类的修饰符  获取的对应数字转换为十进制
            System.out.println("****************************************************************");
            System.out.println("通过getmodifier()获得Student类的修饰符是:"+Modifier.toString(c3.getModifiers()));
            //查看父类
            System.out.println("***************************************");
            System.out.println("通过getsuperclass()获得Student的父类并查看名字:"+c3.getSuperclass().getName());
            //获取类实现的接口
            System.out.println("*********************************************************");
            System.out.println("通过getinterface()获得Student的接口");
            Class []class5=c3.getInterfaces();
            for (Class class1 : class5) {
                System.out.println(class1);
            }
            /*
             * 获取属性的信息
             */
            //获取父类和子类的所有属性
            System.out.println("
    =========================通过反射获得属性相关信息============================
    ");
            Field [] fields=c3.getFields();
            System.out.println("通过getFies()获得父类和子类的所有共有属性:
    ");
            for (Field field : fields) {
                System.out.println(field);
            }
            System.out.println("***************************************************************");
            //获取当前类的所有共有属性
            System.out.println("通过getFies()当前类的所有属性(不论私有共有):
    ");
            Field[] fields1=c3.getDeclaredFields();
            for (Field field : fields1) {
                System.out.println(field);
            }
            System.out.println("**************************************************************");
            //获得指定属性
            Field field3=c3.getDeclaredField("sex");
            System.out.println("获得私有指定的属性:"+field3);
            Field field4=c3.getField("nameString");
            System.out.println("获得共有指定的属性:"+field4);
            //给指定共有属性赋值 
            Student student=(Student) c3.newInstance();
            field4.set(student, "张三");
            System.out.println("给共有属性对象名字赋值:"+student);
            //给指定私有属性赋值
            
            //打开private的开关 之后才能操作数据
            //此处应该应该注意设置值的类型是否和定义属性的类型一致  否则代码编译通过,而运行出错切记切记!!!!
            field3.setAccessible(true);
            field3.set(student, "男");
            System.out.println("给私有属性对象年龄赋值:"+student);
            
            /*
             * 获取类的方法信息
             */
            //获取子类和父类的所有公有方法
            System.out.println("
    ================================获取类中方法的信息========================
    ");
            System.out.println("***********获取子类和父类的所有公有方法****************************");
            Method [] methods=c3.getMethods();
            for (Method method : methods) {
                System.out.println(method);
            }
            //获取当前类方法
            System.out.println("***********获取当前类方法*******************************************");
            Method [] methods2=c3.getDeclaredMethods();
            for (Method method : methods2) {
                System.out.println(method);
                
            }
            //获得指定无参方法
            System.out.println("***********获取当前类方法*******************************************");
            Method method3=c3.getMethod("toString");
            System.out.println("获取的指定方法:"+method3);
            System.out.println("方法的名字:"+method3.getName());
            System.out.println("方法的修饰符:"+Modifier.toString(method3.getModifiers()));
            System.out.println("获得方法的返回值类型:"+method3.getReturnType().getName());
            System.out.println("获取方法的参数:"+Arrays.toString(method3.getParameterTypes()));
            //获得指定带参方法
            Method method4=c3.getDeclaredMethod("sleep", String.class);
            System.out.println("获取的指定方法:"+method4);
            System.out.println("方法的名字:"+method3.getName());
            System.out.println("方法的修饰符:"+Modifier.toString(method4.getModifiers()));
            System.out.println("获得方法的返回值类型:"+method4.getReturnType().getName());
            System.out.println("获取方法的参数:"+Arrays.toString(method4.getParameterTypes()));
            //执行指定方法
            
            System.out.println("************************************************************");
            System.out.println("通过反射执行的共有无参的方法"+    method3.invoke(student));
            method4.setAccessible(true);
            System.out.println("通过反射执行的私有有参的方法"+method4.invoke(student, "name"));
        }
    }

      5.反射的方法总结

     将类结构转换为Class类的实例可以用的方法

    1. 类名.class
    2. new 类名.getClass()
    3. Class.forName(String className)

     获取指定类继承的父类包括实现的接口

        变量名.getSuperclass().getSimpleName()//获取父类的简单名称

        变量名.getInterfaces()//获取所有接口

      获取访问修饰符 

         Modifier.toString(变量名.getModifiers())

       获取所有成员变量

        getField(String name)//获取单个成员变量(只能获取到非私有的)

        getFields()//获取所有成员变量(只能获取到非私有的)

        getDeclaredFields()//获取所有成员变量(都可以获取包括private)

        getDeclaredField()//获取单个成员变量(都可以获取包括private)

        newInstance()//与通过new关键字创建的实例对象一样

        setAccessible(true)//屏蔽字段私有性

        getType().getSimpleName()//获取简单的变量类型

      获取所有成员方法

         getMethods()//所有的方法,包括父类

         getMethods()//获取单个方法,括号里面传的是不定长参数

         getDeclaredMethods()//获取当前类的所有方法,不包含父类

         getDeclaredMethod()//获取当前类的单个方法,括号里面传的是不定长参数

         getParameterTypes()//获取方法的参数

         getReturnType()//返回值类型

     i    nvoke()//执行方法

       获取构造函数

         getConstructor()//获取指定参数的构造函数,括号里传的是不定长参数,类型后面不要忘记加class

         constructor.newInstance()//给获取到的单个构造函数赋值

         getConstructors()//获取所有的构造函数

  • 相关阅读:
    MD53D模型
    WPF 关于变换
    WPF 关于圆角的制作
    [转载]MVVM、MVVMLight、MVVMLight Toolkit之我见
    Surface Pro 调整空间大小
    WPF 图片浏览 伪3D效果
    WPF 实现视频循环播放
    WPF MediElement 视频播放
    WPF INotifyPropertyChanged
    Matlab摄像头视频基本处理
  • 原文地址:https://www.cnblogs.com/wuxuewei/p/11047117.html
Copyright © 2020-2023  润新知