反射应用

本文介绍了Java反射机制的基础知识,包括如何通过反射获取并使用类、构造方法、成员变量和成员方法。详细阐述了获取Class对象的三种方式,以及通过反射创建对象、访问私有成员、调用构造方法和成员方法的步骤。最后提到了通过反射和配置文件动态决定运行类的可能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                             反射基础

class类

java的反射机制是在运行状态中的,对于任意一个类都能够知道这个类的所有的方法和属性。例如 通过Student的具体对象张三---》找到它属于的类Student.class。我们得到Student类之后我们就可以得到类里面所有的方法和属性;所以第一步我们先要获得Class对象:可以理解为类的描述类,就是到底是哪一个类  :Student、Teacher。。。

获得描述类的方法有三种:

1、通过具体的对象获得,例如通过张三获得:每一个对象的顶级父对象Object含有一个getClass()方法,返回该对象所属的类

        String string = new String();
        Class aClass = string.getClass();
        System.out.println(aClass);

2、通过具体的类名 具体的类名即是一个Class对象,Class有一个异常的static class属性,通过该属性可以获得具体的类名

        Class class1 = Long.class;
        System.out.println(class1);

3、通过Class的静态方法forName(“具体的全限定类名”),返回具体的类名

     Class<?> aClass1 = Class.forName("java.lang.Long");
        System.out.println(aClass1);

反射构造方法

获取构造方法,步骤如下:

1. 获取到Class对象,即获得描述类对象clazz

2. 获取构造方法

通过clazz对象的getConstructors()或者getConstructor(“具体的构造参数的描述类对象,例如:String.class”)获得public权限的

如果想获得私有的需要加上Declared,例如:getDeclaredConstructor();然后使用构造方法的setAccessible(true);//取消 Java 语言访问检查

3. 通过构造方法类Constructor中的方法,创建对象,例如具体的学上张三

            a)通过构造方法的newInstance('具体获得构造方法时传入的类型'),无参构造可以不填写

             b)快捷方式,通过默认的public 权限的无参获得 直接描述类对象clazz.newInstance();

import java.lang.reflect.Constructor;

/**
 * <p>ProjectName: Test</p>
 * <p>ClassName: ReflectDemo02</p>
 * <p>Description: 从class对象中获得所需要的成员 </p>
 * <p>Company:www.ecostor.biz </p>
 *Constructor类:描述构造方法对象的类
 * @version 1.0
 * @author jiewenbo
 * @date 2019/5/11 11:03
 */
public class ReflectDemo02 {
    public static void main(String[] args) throws Exception{
        //获得类对象
        Class<?> unitInfo = Class.forName("UnitInfo");
        //通过class文件对象过的构造方法,获得class文件对象中所有的公共的构造方法
//        Constructor<?>[] constructors = unitInfo.getConstructors();
//        for(Constructor temp: constructors){
//            System.out.println(temp);
//        }
        Constructor<?> constructor = unitInfo.getConstructor();
        System.out.println(constructor);
        //运行构造器 通过Constructor类的newInstance.获得对象
        Object o = constructor.newInstance();

    }
}
import java.lang.reflect.Constructor;

/**
 * <p>ProjectName: Test</p>
 * <p>ClassName: ReflectDemo03</p>
 * <p>Description: 通过反射获得有参的构造方法并运行 </p>
 * <p>Company:www.ecostor.biz </p>
 *
 * @version 1.0
 * @author jiewenbo
 * @date 2019/5/11 11:24
 */
public class ReflectDemo03 {
    public static void main(String[] args) throws Exception{
        //获得类对象
        Class<?> unitInfo = Class.forName("UnitInfo");
        Constructor<?> constructor = unitInfo.getConstructor(String.class);
        System.out.println(constructor);
        //运行构造器 通过Constructor类的newInstance.获得对象
        UnitInfo o = (UnitInfo)constructor.newInstance("nihao");
        System.out.println(o.getUnitCode());

    }
}
/**
 * <p>ProjectName: Test</p>
 * <p>ClassName: ReflectDemo04</p>
 * <p>Description: 反射获得构造方法,并运行(快捷方式):前提时该对象必须有无参的构造方法,构造方法的权限必须是public</p>
 * <p>Company:www.ecostor.biz </p>
 *
 * @version 1.0
 * @author jiewenbo
 * @date 2019/5/11 11:32
 */
public class ReflectDemo04 {
    public static void main(String[] args) throws Exception{
        Class<?> unitInfo = Class.forName("UnitInfo");
        //Class类方法中定义了一个方法T newInstance();直接创建别反射对象
        Object o = unitInfo.newInstance();
    }
}

通过反射获取成员变量并使用

反射成员变量

在反射机制中,把类中的成员变量使用类Field表示。可通过Class类中提供的方法获取成员变量:

  1. 返回一个成员变量
    1. public Field getField(String name) 获取指定的 public修饰的变量
    2. public Field getDeclaredField(String name) 获取指定的任意变量
  2. 返回多个成员变量
    1. public Field[] getFields() 获取所有public 修饰的变量

              2.public Field[] getDeclaredFields() 获取所有的 变量 (包含私有)

public class FieldDemo {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
		//获取Class对象
		Class c = Class.forName("cn.itcast_01_Reflect.Person");
		
		//获取成员变量
		//多个变量
		//Field[] fields = c.getFields();
		Field[] fields =  c.getDeclaredFields();
		for (Field field : fields) {
			System.out.println(field);
		}
		System.out.println("-----------------");
		//一个变量
		//public int age;
		Field ageField = c.getField("age");
		System.out.println(ageField);
		
		//private String address
		Field addressField = c.getDeclaredField("address");
		System.out.println(addressField);
	}
}

使用成员变量

获取成员变量,步骤如下:

1. 获取Class对象

2. 获取构造方法

3. 通过构造方法,创建对象

4. 获取指定的成员变量(私有成员变量,通过setAccessible(boolean flag)方法暴力访问)

5. 通过方法,给指定对象的指定成员变量赋值或者获取值

      1. public void set(Object obj, Object value)

在指定对象obj中,将此 Field 对象表示的成员变量设置为指定的新值

      1. public Object get(Object obj)

                    返回指定对象obj中,此 Field 对象表示的成员变量的值

import java.lang.reflect.Field;

/**
 * <p>ProjectName: Test</p>
 * <p>ClassName: ReflectDemo06</p>
 * <p>Description: 反射成员变量并修改值</p>
 * <p>Company:www.ecostor.biz </p>
 *
 * @author jiewenbo
 * @version 1.0
 * @date 2019/5/11 15:18
 */
public class ReflectDemo06 {
    public static void main(String[] args) throws Exception {
        Class unitInfo = Class.forName("UnitInfo");
        Object o = unitInfo.newInstance();
        //通过getFields(),获得所有的公共的成员变量 返回值Field[] Field类获得成员变量的对象
        Field[] fields = unitInfo.getDeclaredFields();
        for (Field temp : fields) {
            System.out.println(temp);
        }

        //获得指定的成员变量 Class类的方法 getField(成员变量的名字)
        Field unitCode = unitInfo.getDeclaredField("unitCode");
        //修改变量的值 使用的是Field 的 void set("Object的对象","值") Object对象指的是当前反射的Class的对象
        unitCode.setAccessible(true);
        System.out.println(unitCode);
        unitCode.set(o, "aaaaaaa");
        System.out.println(unitCode.get(o));

    }
}

通过反射获取成员方法并使用

反射成员方法

在反射机制中,把类中的成员方法使用类Method表示。可通过Class类中提供的方法获取成员方法:

  1. 返回获取一个方法:

                public Method getMethod(String name, Class<?>... parameterTypes)

                         获取public 修饰的方法

                public Method getDeclaredMethod(String name, Class<?>... parameterTypes)

                         获取任意的方法,包含私有的

                         参数1: name 要查找的方法名称; 参数2: parameterTypes 该方法的参数类型

   2.返回获取多个方法:

              1. public Method[] getMethods() 获取本类与父类中所有public 修饰的方法

              2. public Method[] getDeclaredMethods() 获取本类中所有的方法(包含私有的)

public class MethodDemo {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
		//获取Class对象
		Class c = Class.forName("cn.itcast_01_Reflect.Person");
		
		//获取多个方法
		//Method[] methods = c.getMethods();
		Method[] methods = c.getDeclaredMethods();
		for (Method method : methods) {
			System.out.println(method);
		}
		
		System.out.println("-----------------------");
		//获取一个方法:
		//public void method1()
		Method method = c.getMethod("method1", null);
		System.out.println(method);
		//public String method4(String name){
		method = c.getMethod("method4", String.class);
		System.out.println(method);
		//私有方法
		//private void method5()
		method = c.getDeclaredMethod("method5", null);
		System.out.println(method);
	}
}

通过反射,创建对象,调用指定的方法

获取成员方法,步骤如下:

1. 获取Class对象

2. 获取构造方法

3. 通过构造方法,创建对象

4. 获取指定的方法

5. 执行找到的方法

        public Object invoke(Object obj,  Object... args)

        执行指定对象obj中,当前Method对象所代表的方法,方法要传入的参数通过args指定。

import java.lang.reflect.Method;
import java.util.Map;

/**
 * <p>ProjectName: Test</p>
 * <p>ClassName: ReflectDemo07</p>
 * <p>Description: 反射获取成员方法并运行</p>
 * <p>Company:www.ecostor.biz </p>
 *
 * @author jiewenbo
 * @version 1.0
 * @date 2019/5/11 15:35
 */
public class ReflectDemo07 {
    public static void main(String[] args) throws Exception {
        Class<?> unitInfo = Class.forName("UnitInfo");
        Object o = unitInfo.newInstance();
        //使用Class 的getMethods()获得成员变量的所有的公共的成员方法,包括继承的
        Method[] methods = unitInfo.getMethods();
        for (Method temp : methods) {
            System.out.println(temp);
        }
        //获取指定的方法  getMethod()
        Method getId = unitInfo.getMethod("getId");
        System.out.println(getId);
        //通过Method 类中的invoke来调用
        Object invoke = getId.invoke(o);
        System.out.println(invoke);


    }
}

通过反射和配置文件来决定要运行的类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值