欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

反射学习笔记

程序员文章站 2024-03-23 14:37:40
...

为什么使用反射

比如某公司定义了一组接口,然后第三方公司按照这个公司的接口实现了一套功能,然后交给这个公司,但是这个公司的项目已经结束,如何实现动态加载第三方公司提供的功能。

什么是反射

反射就是把Java类中的各种成分映射成一个个的Java对象。例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。

反射常用类

  • Class类—可获取类和类的成员信息
  • Field类—可访问类的属性
  • Method类—可调用类的方法
  • Constructor类—可调用类的构造方法

使用反射的步骤

1.导入java.lang.reflect.*

​2.获得需要操作的类的Java.lang.Class对象

​3.调用Class的方法获取Field、Method等对象

​4.使用反射API进行操作(设置属性﹑调用方法)

Class类

Class类是反射的起源和入口
  • 每个类都有自己的Class对象
  • 提供了获取类信息的相关方法
  • Class类继承自Object类
Class类存储类的结构信息
  • 类名
  • 父类﹑接口
  • 方法﹑构造方法﹑属性
  • 注释
获取Class对象的方法

1.类名.getClass

//方法1:对象.getClass()
Student stu=new Student();
Class clazz=stu.getClass();

2.类名.Class

//方法2:类.class
clazz= Student.class;
clazz=String.class;

3.Class.forname(“stu”);推荐这种方法,耦合度低

//方法3:Class.forName()
clazz=Class.forName("java.lang.String");
clazz=Class.forName("java.util.Date");
获取类的其他信息
Class clazz = Class.forName("java.lang.Object");
Field fields[ ] = clazz.getDeclaredFields();//获取Field 对象  属性 
Method methods[] = clazz.getDeclaredMethods();//获取Method 对象  方法
Constructor constructors[] = clazz.getDeclaredConstructors();//获取Constructor对象   构造方法
动态创建对象方法

1.使用Class的newInstance()方法,仅限于无参构造

Class clazz=Class.forName("com.qf.reflection.Student");
Object obj=clazz.newInstance();	

2.使用Constructor方法的newInstance()方法,适用于所有构造方法

Constructor cons = clazz.getConstructor(new Class[]{ String.class,  int.class, float.class });
Object obj = cons.newInstance(new Object[ ] {"lkl", 32, 56.5f });

通过反射获取类的各种信息:

类:

package com.qf;

/*
 * wgy 2019/8/16 9:55
 * 佛祖保佑,永无BUG!
 */
public class Person extends AbstractPerson<String> implements Comparable<String>{
    //成员变量
    private String name;
    private int age;
    private String gender;
    //构造方法
    public Person() {
    }

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

    //方法
    //无参无返回值
    public void show(){
        System.out.println("姓名:"+name+" 年龄:"+age+" 性别:"+gender);
    }
    //有参无返回值
    public void show(String address){
        System.out.println("姓名:"+name+" 年龄:"+age+" 性别:"+gender+" 地址:"+address);
    }
    //带返回值的方法
    public String getInfo(){
        return "信息:"+name+"  "+age+"  "+gender;
    }

    //静态方法
    public static void print(){
        System.out.println("这是一个静态方法");
    }

    //私有方法
    private void show(String address,String email){
        System.out.println("地址:"+address+"  邮箱:"+email);
    }

    @Override
    public int compareTo(String o) {
        return 0;
    }

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

反射获得信息

package com.qf;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

/*
 * 使用反射技术操作Person
 * (1)获取类的类对象
 * (2)获取类中构造方法
 * (3)获取方法
 */
public class Demo1 {
    public static void main(String[] args) throws Exception {
//        getClazz();
        //getConstructor();
//        getMethod();
        getField();

    }
    //(1)获取类的类对象
    public static void  getClazz() throws Exception{
        //方式1:使用class属性获取
        Class<?> clazz1=Person.class;
        System.out.println(clazz1.hashCode());
        //方法2  使用getClass方法
        Person shaobo=new Person();
        Class<?> clazz2 = shaobo.getClass();
        System.out.println(clazz2.hashCode());
        //方式3  使用Class.forName方法:耦合性低,不依赖于具体的类,可以编译通过
        Class<?> clazz3=Class.forName("com.qf.Person");
        System.out.println(clazz3.hashCode());
        //扩展
        //获取父类
        Class<?> superclass = clazz3.getSuperclass();
        System.out.println(superclass.getName());
        //获取父类泛型
        Type genericSuperclass = clazz3.getGenericSuperclass();
        System.out.println(genericSuperclass.getTypeName());
        //获取接口
        Class<?>[] interfaces = clazz3.getInterfaces();
        System.out.println(interfaces.length);
        for (Class<?> anInterface : interfaces) {
            System.out.println(anInterface.toString());
        }
        //获取包名
        Package aPackage = clazz3.getPackage();
        System.out.println(aPackage.getName());

    }	
    
 
    public static void getConstructor() throws Exception{
        Class<?> clazz=Class.forName("com.qf.Person");
        //1获取构造方法
        Constructor<?>[] constructors = clazz.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("--------------------------");
        //2获取单个构造方法
        //2.1获取无参构造方法
        Constructor<?> constructor = clazz.getConstructor();
        //2.2获取带参
        Constructor<?> constructor1 = clazz.getConstructor(String.class, int.class, String.class);
        System.out.println(constructor);//输出的是Person 的无参构造方法
        System.out.println(constructor1);//输出的是Person的有参构造方法,包括参数所在的包
        //3利用构造方法创建对象
        System.out.println("---------利用构造方法创建对象------------");
        Person zhangsan=new Person();
        Object lisi = constructor.newInstance();
        System.out.println(zhangsan);
        System.out.println(lisi);

        Object wangwu = constructor1.newInstance("王五", 20, "男");
        System.out.println(wangwu);

        //简单创建对象的方法
        Object o = clazz.newInstance();
        System.out.println(o.toString());

    }

	//获取方法
    public static void getMethod() throws Exception{
        //1获取无参的方法
        Class<?> clazz=Class.forName("com.qf.Person");
        //Method[] methods = clazz.getMethods();//获取公类自己公开的方法,继承的公开方法
//        Method[] methods = clazz.getDeclaredMethods();//获取公类自己所有的方法,包括非公开的方法
//        System.out.println("-----------getMethods();----------");
//        for (Method method : methods) {
//            System.out.println(method);
//        }

//        Person p=new Person();
//        p.show();
        Object zhangsan = clazz.newInstance();
        Method show = clazz.getMethod("show");
        show.invoke(zhangsan);// zhangsan.show();

        //2获取有参
        Method show2=clazz.getMethod("show",String.class);
        show2.invoke(zhangsan, "北京");

        //3获取带返回值的方法
        Method getInfo = clazz.getMethod("getInfo");
        Object value=getInfo.invoke(zhangsan);
        System.out.println(value);

        //4获取静态方法
        Method print = clazz.getMethod("print");
        print.invoke(null);// Person.print();

        //5私有方法
        Method show3 = clazz.getDeclaredMethod("show", String.class, String.class);
        //设置访问权限无效
        show3.setAccessible(true);
        show3.invoke(zhangsan, "上海","[email protected]");
    }

    public static void getField() throws  Exception{
        //1获取类对象
        Class<?> clazz = Class.forName("com.qf.Person");
        //2获取
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        //获取单个
        System.out.println("--------------------------");
        Field name = clazz.getDeclaredField("name");
//
//        Person wangwu=new Person();
//        wangwu.name="王五";
        Object wangwu = clazz.newInstance();

        //赋值
        name.setAccessible(true);
        name.set(wangwu, "王五");//  wangwu.name="王五";

        //获取
        Object object=name.get(wangwu);// wangwu.name
        System.out.println(object);
    }
}
相关标签: 反射