java--02--反射

1 类初始化的时机

class Temp{
	
	static{
		System.out.println("执行Temp初始化代码块");
	}
}

public class TextDemo_02 {
	
	public static void main(String[] args){
		System.out.println("执行ClassLoader的loadClass方法");
		ClassLoader classLoader=ClassLoader.getSystemClassLoader();
		try {
			classLoader.loadClass("Temp");//如果出现无法加载类的情况下,可能使不同的包有相同的类名,添加类的全限定名即可。
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("结束执行ClassLoader的loadClass方法");
		System.out.println("------------分割线--------------");
		System.out.println("开始执行Class的forName方法");
		try {
			Class.forName("Temp");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("结束执行Class的forName方法");
	}
}

使用ClassLoader类的loadClass()方法来加载某个类时,该方法只加载该类,不会执行该类的初始化代码块,但是使用Class的forName()时会强制初始化该类

2创建对象

方法一:通过Class的newInstance方法创建对象

        /**
	 * 存放类名对应的对象
	 */
	private static Map<String, Object> mapStrObj = new HashMap<String, Object>();

	private static String a;
	private static String b;

	// 初始化类名
	static {
		// 加载配置文件
		Properties pp = new Properties();
		InputStream inputStrea = Object.class
				.getResourceAsStream("/object.properties");
		try {
			pp.load(inputStrea);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// 读取配置文件中的信息
		a = pp.getProperty("a");
		b = pp.getProperty("b");
	}

	public TextDemo_02() {
		// TODO Auto-generated constructor stub
		System.out.println("正在执行TextDemo_02的构造方法,正在创建TextDemo_02对象");
	}

	/**
	 * 生成对象
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws ClassNotFoundException
	 */
	public static void createObject() throws InstantiationException,
			IllegalAccessException, ClassNotFoundException {
		// 创建对象并添加到map中
		Class<?> classA = Class.forName(a);
		mapStrObj.put(a, classA.newInstance());

		Class<?> classB = Class.forName(b);
		mapStrObj.put(b, classB.newInstance());
	}

	public static void main(String[] args) {
		try {
			TextDemo_02.createObject();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		mapStrObj.get("TextDemo_02");
	}

object.properties文件中的信息:

a=TextDemo_01
b=TextDemo_02
 

方法二 :通过Constructor对象的newInstance方法来创建对象

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * 创建对象的第二种方法:调用Constructor的newInstance方法
 * 
 * @author Shipp
 *
 */
public class TextDemo_03 {

	/**
	 * 定义一个构造方法
	 * 
	 * @param str
	 */
	public TextDemo_03(String str) {
		System.out.println("TextDemo_03有参构造方法传的参数:" + str);
		System.out.println("正在执行TextDemo_03构造函数,正在创建TextDemo_03对象");
	}

	/**
	 * 创建对象
	 * 
	 * @throws ClassNotFoundException
	 * @throws NoSuchMethodException
	 * @throws RuntimeException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public static void createObject() throws ClassNotFoundException,
			NoSuchMethodException, RuntimeException, InstantiationException,
			IllegalAccessException, InvocationTargetException {

		Class<?> class1 = Class.forName("TextDemo_03");// 根据类名获取对象
		Constructor constructor = class1.getConstructor(String.class);// 获取类中一个带字符串的构造方法
		Object obj = constructor.newInstance("创建对象");// 创建对象

	}

	public static void main(String[] args) {
		try {
			TextDemo_03.createObject();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

3 调用方法

/**
	 * 被调用的方法
	 * @param str
	 */
	public static void runMethod(String str){
		System.out.println("正在执行TextDemo_02的runMethod方法,参数值为"+str);
	}

	/**
	 * 执行调用参数
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	public static void invokingMethod() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		//获取对象
		Object object=mapStrObj.get("TextDemo_02");
		//获取实现类所对应的Class对象
		Class<?> tarClass=object.getClass();
		//获取希望调用的方法,第一个参数是方法名,从第二个参数开始是对应的形参类型
		Method method=tarClass.getMethod("runMethod",String.class);
		//执行调用,第一个参数是对象,第二个参数是要传的实参
		method.invoke(object, "传递进去的参数");
	}

4 获取和修改成员变量值

	@Test
	public void test03() throws NoSuchFieldException, IllegalAccessException {
		class User{

			private String userName;

			public User(String userName) {
				this.userName = userName;
			}

			public String getUserName() {
				return userName;
			}

			public void setUserName(String userName) {
				this.userName = userName;
			}
		}
		//获取对象中指定字段的值
		Field field = User.class.getDeclaredField("userName");
		field.setAccessible(true);
		Object o = field.get(new User("u1"));
		System.out.println(o);

		//修改对象中指定字段的值
		User u2 = new User("u2");
		field.set(u2, "u3");
		System.out.println(JSON.toJSONString(u2));
	}

getDeclaredField是可以获取一个类的public字段.,getField只能获取类的所有 字段.  
 


5操作数组

//创建元素类型为String类型 长10的数组
		Object object=Array.newInstance(String.class,10);
		//为数组中赋值,第一个参数为操作的对象,第二个参数为设置值的索引,第三个参数为值
		Array.set(object, 0, "0");
		Array.set(object, 1, "1");
	
		//从数组中取数据,第一个参数为操作的对象,第二个为索引
		Object object0=Array.get(object, 0);
		Object object1=Array.get(object, 1);
		System.out.println(object0);
		System.out.println(object1);		Object object=Array.newInstance(String.class,10);
		//为数组中赋值,第一个参数为操作的对象,第二个参数为设置值的索引,第三个参数为值
		Array.set(object, 0, "0");
		Array.set(object, 1, "1");
	
		//从数组中取数据,第一个参数为操作的对象,第二个为索引
		Object object0=Array.get(object, 0);
		Object object1=Array.get(object, 1);
		System.out.println(object0);
		System.out.println(object1);

执行结果:

java.lang.ClassNotFoundException: TextDemo_03

因为你用的不是全类名,虚拟机是根据全类名(包名.类名)寻找相应的程序的
参考博客:https://zhidao.baidu.com/question/431605041629845604.html 

实际应用:判断对象中部分字段是否全不为空

    public static boolean isObjFieldNull(Object obj, List<String> checkFieldList) {
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if (!checkFieldList.contains(field.getName())) {
                continue;
            }
            Object fieldValue;
            try {
                fieldValue = field.get(obj);
            } catch (IllegalAccessException e) {
                System.out.println("获取对象字段值异常:" + e.getMessage());
                continue;
            }
            if (fieldValue == null) {
                return true;
            }
            if (fieldValue instanceof String) {
                if (((String) fieldValue).length() == 0) {
                    return true;
                }
            }
        }
        return false;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值