JavaSE之反射

反射概述

反射就是根据字节码文件,反射类的信息,方法,构造方法,字段等类的内容,根据字节码文件创建对象,调用方法的技术

反射的基础是Class对象
把一组小狗可以抽象为Dog类,把一组小猪抽象为pig类,把一组人抽象为Person类,把Dog/Pig/Person/String/System等所有的类抽象为Class类, Class类描述所有的类的共同特征

如何获得Class对象?

  1. 每个类都有class属性 Class class1 = Test01.class;
  2. 每个对象都有getClass()方法 Class class2 = new Test01().getClass();
  3. Class.forName(完整类名)
    Class class3 = Class.forName(“com.node.chapter08.demo01.Test01”);
    注意:Class<?> class4 = int.class;
    Class<?> class6 = Integer.TYPE;
    System.out.println( class4 == class6 ); //true
    Class.forName()返回Class对象时,会把参数指定的类加载到内存中

反射类信息

class1.getModifiers() 返回类的修饰符
class1.getName() 返回完整类名
class1.getSimpleName() 简易类名
class1.getSuperClass() 父类
class1.getInterfaces() 接口

public static void main(String[] args) {
		//1)创建Class对象
		Class<?> class1 = String.class;				
//		Class<?> class1 = Integer.class;				
		
		StringBuilder sb = new StringBuilder();
		//2)反射类的信息
		//2.1 修饰符
		int mod = class1.getModifiers(); 		//方法返回类的修饰符,是一个整数
		String modifier = Modifier.toString(mod);
		sb.append( modifier );
		//2.2 类名
		sb.append(" class  ");
//		sb.append( class1.getName() ) ; 		//getName()r返回完整类名 
		sb.append( class1.getSimpleName() ) ; 	//返回简易类名 
		
		//2.3 父类
		Class<?> superclass = class1.getSuperclass();
		//判断父类是否为Object
		if ( Object.class != superclass ) {
			sb.append(" extends ");
			sb.append( superclass.getSimpleName() );			
		}
		
		//2.4 接口,getInterfaces()返回接口数组, 如果类没有实现接口,返回的数组长度为0
		Class<?>[] interfaces = class1.getInterfaces();
		if( interfaces.length > 0 ){ 		//实现了接口
			sb.append(" implements ");
			//遍历接口数组
			for( int i = 0 ;  i<interfaces.length ; i++){
				sb.append( interfaces[i].getSimpleName() );
				//接口之间使用逗号分隔
				if ( i < interfaces.length - 1) {
					sb.append(",");
				}
			}
		} 
		
		System.out.println( sb );
	}

访问字段

通过反射技术访问字段
class1.getField(字段名) 返回指定字段名的公共字段
class1.getDeclaredField(字段名) 返回指定名称的字段(即使它是私有的)
class1.newInstance() 创建一个实例(创建一个对象)
field.set(对象名, 字段的值); 设置字段的值
field.get(对象名); 返回字段的值
field.setAccessible(true); 设置字段的可访问性

	public static void main(String[] args) throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
		//1) 创建Class对象, 
		Class<?> class1 = Person.class;
		
		//2) 反射name字段
		Field nameF = class1.getField("name");
		
		//3) 通过反射技术创建对象(实例), 默认调用类的无参构造
		Object p1 = class1.newInstance(); 			//相当于new Person()
		
		//4)设置字段的值
		nameF.set(p1, "lisi"); 				//p1.setName("lisi")
		
		//5)返回字段的值
		System.out.println( p1 );
		System.out.println( nameF.get(p1) );		//p1.getName()
		
		//6)访问私有字段: age
//		Field ageF = class1.getField("age"); 		//只能返回公共字段
		Field ageF = class1.getDeclaredField("age"); 		//返回字段
		ageF.setAccessible(true); 				//设置字段的可访问性
		ageF.set(p1, 18);
		System.out.println( ageF.get(p1));
		System.out.println( p1 );
	}

访问方法

通过反射技术调用方法
class1.getMethod(方法名, 参数类型列表) 反射指定方法签名的公共方法 method.invoke(实例名, 方法的实参列表) 调用方法

public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//1) 创建Class对象
		Class<?> class1 = Person.class;
		
		//2) 反射show()方法
		Method showM = class1.getMethod("show", null);
		
		//3)通过反射技术创建实例
		Object obj = class1.newInstance();			//new Person()
		
		//4)调用方法
		showM.invoke(obj, null); 		//obj.show()
		
		//5)反射set(String, int)方法
		Method setM = class1.getMethod("set", String.class , int.class );
		setM.invoke(obj, "lisi", 66);
		
		showM.invoke(obj);
		System.out.println( obj );
	}

读取配置文件的信息

有时会把类名保存到配置文件中, 通过Properties读取配置文件的类名 , 通过反射创建对象

public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
		//读取配置文件的类名
		Properties properties = new Properties();
		InputStream inStream = Test.class.getResourceAsStream("/com/bjpowernode/chapter08/demo02/config.properties");
		properties.load(inStream);		
		String className = properties.getProperty("classname");
		//通过反射技术,根据完整类名创建对象
		Class<?> class1 = Class.forName(className);
		
		Collection<?> collection =  (Collection<?>) class1.newInstance();
		
		
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值