Java29- 反射

反射

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

反射的基础,是class的对象

  • 每一个类都有class属性
  • 每个对象都有getClass() 方法
  • Class.forName(完整类名)

Class.forName 返回Class对象时,回把参数指定的类加载到内存中

Class<?> class7 = Person.class;   //没有执行Person类静态代码块, 说明Person类没有加载内存
Class<?> class8 = Class.forName("com.bjpowernode.chapter08.demo01.Person");  //执行了静态代码块, 说明类加载了内存

反射类的信息

java.lang.reflect包中有反射相关的类

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

创建Class对象

Class<?> class1 = String.class;

反射类的信息
修饰类 Modifiers:修饰器

class1.getModifiers();

Modifier.toString(mod);//整数转换为字符串

类名

Simple简单

class1.getName() 返回完整类名

class1.getSimpleName() //返回简易类名

父名

class1.getSuperClass();

	Class<?> superclass = class1.getSuperclass();
		//判断父类是否为Object
		if ( Object.class != superclass ) {
			sb.append(" extends ");
			sb.append( superclass.getSimpleName() );			
		}
接口

getInterfaces()返回接口数组, 如果类没有实现接口,返回的数组长度为0

class1.getInterfaces();

		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(",");
				}
			}
		} 

通过反射技术访问字段

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

​ Class<?> class1 = Person.class;

反射name字段

​ Field nameF = class1.getField(“name”);

通过反射技术创建对象(实例),默认调用类的无参构造

​ Object p1 = class1.newInstance(); //相当于new Person()

设置字段的值

nameF.set(p1, “lisi”); //p1.setName(“lisi”)

返回字段的值

​ System.out.println( p1 );
​ System.out.println( nameF.get(p1) ); //p1.getName()

访问私有字段 age
Object p1 = class1.newInstance(); 			//相当于new Person()

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 );
	}

代码

Person类
public class Person {

	static{
		System.out.println("静态代码块, 在类加载内存后执行");
	}
	
	public String name; 		
	private int age;
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
	public void show() {
		System.out.println("name:" + name + ",age:" + age);
	}
	
	public void set(String name, int age) {
		this.age = age;
		this.name = name;
	}
	
}
创建Class对象的方式
public class Test01 {

	public static void main(String[] args) throws ClassNotFoundException {
		//1) 每个类都有一个Class属性
		Class class1 = Test01.class;
		
		//2)每个 对象有getClass()
		Class class2 =  new Test01().getClass();
		
		//3) Class.forName()
		Class class3 = Class.forName("com.bjpowernode.chapter08.demo01.Test01");
		
		System.out.println( class1 );
		//
		System.out.println( class1 == class2 );
		System.out.println( class2 == class3 );
		 
		//4)
		Class<?>  class4 = int.class;
		Class<?> class5 = Integer.class;
		System.out.println( class4 == class5 ); 	 //false
		Class<?> class6 = Integer.TYPE;
		System.out.println( class4 == class6 ); 	//true
		
		//5) Class.forName()r返回Class对象时, 会把参数指定的类加载到内存中
//		Class<?> class7 = Person.class;   //没有执行Person类静态代码块, 说明Person类没有加载内存
		Class<?> class8 = Class.forName("com.bjpowernode.chapter08.demo01.Person");  //执行了静态代码块, 说明类加载了内存
		
		
	}

}
反射类的信息
public class Test02 {

	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 );
	}

}
通过反射技术访问字段
public class Test03 {

	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 );
	}

}
通过反射技术调用方法
public class Test05 {

	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 );
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值