初学——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("\n=========================通过反射获得类构造==================\n");
        //方法一:
        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("\n=========================通过反射获得类的相关信息==================\n");
        //获取类的名字
        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("\n=========================通过反射获得属性相关信息============================\n");
        Field [] fields=c3.getFields();
        System.out.println("通过getFies()获得父类和子类的所有共有属性:\n");
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("***************************************************************");
        //获取当前类的所有共有属性
        System.out.println("通过getFies()当前类的所有属性(不论私有共有):\n");
        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("\n================================获取类中方法的信息========================\n");
        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()//获取所有的构造函数

posted @ 2019-06-19 18:54  Sprio丨往昔  阅读(184)  评论(0编辑  收藏  举报