Java反射

反射相关知识
  1. Class
    Class类的实例表示正在运行的Java应用程序中的类和接口
  2. Constructor
    关于类的单个构造方法的信息以及对它的访问权限
  3. Field
    Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限.
  4. Method
    Method 提供关于类或接口上单独某个方法的信息
  5. setAccessible(true);//通过该设置可以访问类中私有属性(可以提高反射执行效率减小程序执行时间)
获取类的方法

已知类和对象的情况下

  1. 类名.class
  2. 对象.getClass() — Object 类提供
  3. 未知类和对象的情况下Class.forName(“包名.类名”)
 String path="com.DW.bean.User";//表示User类的全路径名(包名+类名)
  Class clazz=Class.forName(path);//通过Class.forName()方法获取类
   //获取类名
      System.out.println(clazz.getName());//运行结果 包名+类名:com.DW.bean.User
      System.out.println(clazz.getSimpleName());//运行结果 类名:User
获取类的属性方法
  1. getField()和getFields()只能获取public修饰的属性
  2. getDeclaredField()和getDeclaredFields()可以获取所有属性
       //getField()和getFields()只能获取public修饰的属性
   Field field=clazz.getField("a");//传入public修饰的属性名返回属性
   Field[] fields=clazz.getFields();//获取所有public修饰的属性并返回在数组中
        //getDeclaredField()和getDeclaredFields()可以获取所有属性
  Field field=clazz.getDeclaredField(); //传入属性名返回属性
  Field[] fields=clazz.getDeclaredFields();//返回所有属性返回到数组中
获取类的方法的方法
  1. .getMethod()和getMethods()可以获取public修饰的方法
  2. getDeclaredMethod()和getDeclaredMethods()可以获取所有方法
  //.getMethod()和getMethods()可以获取public修饰的方法
  Method method=clazz.getMethod("");//传入public修饰的方法名返回方法
  Method[] methods=clazz.getMethods();//获取所有public修饰的方法并返回在数组中
  //getDeclaredMethod()和getDeclaredMethods()可以获取所有方法
  Method method=clazz.getDeclaredMethod("getUname");//第一个参数表示方法名称,第二个参数表示方法的参数类型
 Method method1=clazz.getDeclaredMethod("setUname", String.class);//String.class表示传入方法的参数类型为string类型
 Method[] methods=clazz.getDeclaredMethods();//可以获取所有方法并返回到数组中
获取类构造器方法

1…getConstructor()和getConstructors()可以获取public修饰的方法
2.getDeclaredConstructors();和getDeclaredConstructor()可以获取所有构造方法

 // 获取public修饰的构造器
 Constructor constructor=clazz.getConstructor();//传入参数类型来获取public修饰的构造器没有参数可以不写
 Constructor[] constructors=clazz.getConstructors();
     //获取所以构造器
  Constructor[] constructors=clazz.getDeclaredConstructors();
  Constructor constructor=clazz.getDeclaredConstructor();//传入构造器的参数类型来区分获取的构造器

通过反射动态调用构造器、方法、属性

创建一个bean

package com.DW.bean;

public class User {
    private int id;
    private int age;
    private String uname;
    public User() {
    }

    public User(int id, int age, String uname) {
        this.id = id;
        this.age = age;
        this.uname = uname;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }
}

创建测试

import com.DW.bean.User;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 通过反射动态调用构造器、方法、属性
 */
public class test02 {
    public static void main(String[] args) {
        String path="com.DW.bean.User";//表示User类的全路径名(包名+类名)
        try {
            Class<User> clazz=(Class<User>) Class.forName(path);//通过Class.forName()方法获取类
            //通过反射调用构造方法、构造对象
            User u=clazz.newInstance();//创建User对象(其实是调用了User的无参构造方法)

            //通过有参构造器创建对象
                //获取有参构造器
           Constructor<User> c=clazz.getDeclaredConstructor(int.class,int.class,String.class);
           User u2=c.newInstance(1,1000,"李白");
            System.out.println(u2.getUname());

            //通过反射调用普通方法
            Method method=clazz.getDeclaredMethod("setUname", String.class);
            method.invoke(u,"张飞");//相当于u.setUname("张飞");
            System.out.println(u.getUname());

            //通过反射操作属性
            Field f=clazz.getDeclaredField("age");
            f.setAccessible(true);//通过该设置可以访问类中私有属性(可以提高反射执行效率)
            f.set(u,10);//相当于u.setAge(10);
            System.out.println(u.getAge());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

反射小案例

需求:写一个“框架”,可以帮我们在不改变任何代码前提下,创建任意类的对象,并且执行其中任意方法
步骤
1. 将需要创建的对象的全类名和要执行的方法定义在配置文件中
2. 在程序中加载读取到的配置文件
3. 使用反射技术来加载类文件进内存
4. 创建对象
5. 执行方法
具体步骤
创建要创建的类

package com.DW;

public class student {
    public void eat(){
        System.out.println("吃饭");
    }
}

编写配置文件(pro.properties)

# 创建类的全类名
className=com.DW.student
# 创建类的方法名
methodName=eat

创建测试类


import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

class test {
    public static void main(String[] args) throws Exception {
        //加载配置文件
        Properties pro=new Properties();
        //加载配置文件,转化为集合
            //通过类加载器获取文件路径
        ClassLoader classLoader = test.class.getClassLoader();
        InputStream resourceAsStream = classLoader.getResourceAsStream("pro.properties");
        pro.load(resourceAsStream);
        //获取配置文件内容
        String className = pro.getProperty("className");
        String methodName = pro.getProperty("methodName");
        //通过反射加载类创建对象并调用方法
        Class aClass = Class.forName(className);
        Object o = aClass.newInstance();//创建对象
        Method method = aClass.getMethod(methodName);//获取方法
        //执行方法
        method.invoke(o);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值