反射

反射

1.通过反射获取Class类实例的三种方式

第一种方式: 使用对象.getClass()获取该对象的Class实例

Class cls = new Student().getClass();

第二种方式: 类名.class

Class cls = Student.class;

第三种方式: Class.forName("全限定名-即包名.类名"),用类名获取一个Class实例,这种方式比较常用

Class cls = Class.forName("entry.Student");

前两种方法必须明确类型,第三种只要提供这种类型的字符串,拓展性更强,不需要知道类,只要提供字符串按照配置文件加载即可;

2.获取运行时类实现的接口以及父类

//1.获取运行时的类
Class cls = Goods.class;
//2.获取实现的接口,因为接口是多继承,所以使用数组,而类则是单继承的
Class[] interfaces = cls.getInterfaces();//要实现该语句Goods类必须继承了接口

for(Class class1: interfaces){
    //getName()获取名称,该名称是全限定名
    String name = class1.getName();
    
    //getSimpleName()获取简称
     String simpleName = class1.getSimpleName();
}

//3.获取父类
Class cls2 = cls.getSuperclass();

3.通过反射获取构造

  • getConstructor(Class<?>...parameterTypes) 获取指定公共构造
  • getConstructor() 获取本类的公共构造
  • getDeclaredConstructor(Class<?>...parameterTypes) 获取本类指定的构造(公有或者私有)
  • Constructor<?>[] getDeclaredConstructors() 获取本类的所有构造
//1.获取运行时类
Class cls =  Goods.class;

//2.获取构造
//调用getConstructors() 获取本类所有的公共构造
Constructor[] constructors = cls.getConstructors();

getConstructor()-获取指定公共构造

//遍历运行时类里的所有构造
for(Constructor constructor : constructors){
    //获取访问修饰符
    //getModifiers() 返回此类或接口以整数编码的Java语言修饰符
    int modifiers = constructor.getModifiers();
    String string = Modifier.toString(Modifiers);//将int类型修饰符表现形式转换成字符串表现形式
    
	//获取名称
	String name = constructor.getName();
	//获取参数列表
    Class[] parameterTypes = constructor.getParameterTypes();
    for (Class class1 : parameterTypes) {
    	//获取简称
        String simpleName = class1.getSimpleName();
        System.out.println(simpleName);
    }
}

getConstructor(class<?>…parameterTypes)-获取本类指定的构造(公有或者私有)

//获取指定参数的构造
Constructor<Goods> constructor = cls.getConstructor(String.class,Double.class,Integer.class);
//创建对象
Goods goods = constructor.newInstance("张三",125.0,18);
System.out.(goods);

getDeclaredConstructor()方法的演示

Constructor<?>[] declaredConstructors = cls.getDeclaredConstructors();
for ( Constructor<?> constructor2 : declaredConstructors ){
    //获取访问修饰符
    int modifiers = constructor2.getModifiers();
     String string = Modifier.toString(Modifiers);//将int类型修饰符表现形式转换成字符串表现形式
    //获取名称
	String name = constructor2.getName();
	//获取参数列表
	Class<?>[] parameterTypes = constructor2.getParameterTypes ();
    for (class<?> class1 : parameterTypes ){
		//简称
    	System.out.println(class1.getSimpleName());
    }
    System.out.println(string+" "+name);
}

getDeclaredConstructor(Class<?>…parameterTypes) 获取本类指定的构造(公有或者私有)

Constructor<Goods> constructor2 = cls.getDeclaredConstructor(String.class,Integer.class);
//java.lang.IllegalAccessException:非法访问异常,因为Goods之中的属性如果是“private”修饰的就不可以
//Goods goods2 = constructor2.newInstance("娃娃",289);
//为了解决上面的情况,添加如下语句
constructor2.setAccessible(true);//打破封装,忽略对Java访问修饰符的检查
Goods goods2 = constructor2.newInstance("娃娃",289);//创建对象的实例
System.out.println("goods2");

加Declared和不加Declared的区别?
加Declared可以获取本类所有的东西,不加Declared获取本类以及父类公共的东西

加s和不加s的区别?
加s获取多个返回数组,不加s返回单个

4.反射常用的一些方法

  • getName(),获取名称
  • getSimpleName(),获取简称
  • getModifiers(),获取访问修饰符
  • getParameterTypes(),获取参数列表
  • newInstance(),创建对象,con.newInstance(“zhangsan”,20)
Class<Goods> cls = Goods.class;
Goods = cls.newInstance();//调用的是无参构造

5.通过反射获取运行时类中成员变量

getFields():获取本类以及父类所有的公共属性 
getField():获取本类以及父类中指定的属性(只能获取公有的)
getDeclaredFields():获取本类中所有的属性(公有、私有)
getDeclaredField(String name):获取本类中指定的属性(私有、公有都可以获取)

常用方法

set(Object obj,Object value)//第一个参数:指定对象;第二个参数:需要设置的值
get(Object obj)//返回指定对象上此Field表示的字段值,第一个参数:指定的对象

1.获取运行时类

Goods g = new Goods();
Class<? extends Goods> cls = g.getClass();
Goods goods = new Goods("洗发水",12.0,200);

2.getDeclaredFields():获取本类中所有的属性(公有、私有)

Field[] fields = cls.getDeclaredFields();
//遍历每一个属性对象
for(Field field : fields){
	field.setAccessible(true);//打破封装
	//获取访问修饰符
	int modifiers = field.getModifiers();
	String string = Modifier.toString(modifiers);
	//获取属性类型
	Class<?> type = field.getType();
	String simpleName = type.getSimpleName();
	//获取属性名称
	String name = field.getName();
	//获取属性值
	Object value = field.get(goods);
	//设置属性值
	//有个问题?我们在循环里,你给谁设置属性值
	//应该加一个判断,免得不适合设置属性的变量被设置导致报错
	if("id".equals(name)){
		field.set(goods,1);
	}else if("name".equals(name)){
		field.set(goods,"洗面奶");
	}else if("price".equals(name)){
		field.set(goods,34.0);
	}else if("storage".equals(name)){
		field.set(goods,1000);
	}
}

getDeclaredField(String name):获取本类中指定的属性(私有、公有都可以获取)

Field field = cls.getDeclaredFields("name");
field.setAccessible(true);//打破封装
int modifiers = field.getModifiers();
String string = Modifier.toString(modifiers);
Class<?> type = field.getType();
String simpleName = type.getSimpleName();
String name = field.getName();
Object value = field.get(goods);
System.out.println(string+" "+simpleName+" "+name+" "+value);

getFields():获取本类以及父类所有的公共属性

Field[] fields2 = cls.getFields();
for(Field field2 : field2){
	int modifiers2 = field2.getModifiers();
	String string2 = Modifier.toString(modifiers2);
	Class<?> type2 = field2.getType();
	String simpleName2 = type2.getSimpleName();
	String name2 = field2.getName();
}

getField():获取本类以及父类中指定的属性(只能获取公有的)

 Field field2 = cls.getField("gname");
 int modifiers2 = field2.getModifiers();
String string2 = Modifier.toString(modifiers2);
Class<?> type2 = field2.getType();
String simpleName2 = type2.getSimpleName();
String name2 = field2.getName();
//设置属性值
field2.set(goods,"旺财");
//获取属性值
Object val =field.get(goods);

5.通过反射获取成员方法

  • getDeclaredMethods() 获取本类所有的成员方法(公有、私有)
  • geDeclaredMethods(String name, Class<?>...parameterTypes) 获取本类指定的成员方法(公有、私有)
  • getMethods() 获取本类以及父类所有的公共成员方法
  • getMethods(String name, Class<?>...parameterTypes) 获取本类以及父类指定的公共方法
public class Case4 {
	public static void main(String[] args) {
		//1.获取运行时类
		Class cls = Goods.class;
		//创建运行时类实例
		Goods goods = cls.newInstance();
		
		System.out.println("-- getDeclaredMethods() 获取本类所有的成员方法(公有、私有) --");
		Method[] declarMethods = cls.getDeclaredMethods();
		//循环遍历,获取每个方法
		for (Method method : declarMethods) {
			method.setAccessible(true);//打破封装
			//获取访问修饰符
			int modifiers = method.getModifiers();
			String string = Modifier.toString(modifiers);
			//获取返回值类型
			Class<?> returnType = method.getReturnType();
			String simpleName = returnType.getSimpleName();
			//获取方法名称
			String name = method.getName();
			//获取参数列表
			Class<?>[] parameterTypes = method.getParameterTypes();
			for (Class<?> class1 : parameterTypes) {
				System.out.println(class1.getSimpleName());
			}
			System.out.println(string+" "+simpleName+" "+name);
			//调用方法
			//有个问题?在循环内如果直接调用方法,那每个方法都会被执行,但是我们方法中参数不一样,所以如果需要调用方法需要判断
			if (name.equals("setName")) {
				//调用方法
				//第一个参数:底层调用方法的对象,第二个参数:用于方法调用的参数
				method.invoke(goods, "再坚持坚持就可以用膳");
			}
		}
		System.out.println(goods);
		
		
		System.out.println("-- geDeclaredMethods(String name, Class<?>...parameterTypes) 获取本类指定的成员方法(公有、私有) --");
		Method method = cls.getDeclaredMethod("toString");
		//获取访问修饰符
		int modifiers = method.getModifiers();
		String string = Modifier.toString(modifiers);
		//获取返回值类型
		Class<?> returnType = method.getReturnType();
		String simpleName = returnType.getSimpleName();
		//获取方法名称
		String name = method.getName();
		System.out.println(string+" "+simpleName+" "+name);
		//调用方法
		Object value = method.invoke(goods, null);
		System.out.println(value);
		
		
		System.out.println("-- getMethods() 获取本类以及父类所有的公共成员方法 --");
		Method[] methods = cls.getMethods();
		for (Method method2 : methods) {
			//获取访问修饰符
			int modifiers2 = method2.getModifiers();
			String string2 = Modifier.toString(modifiers2);
			//获取名称
			String name2 = method2.getName();
			//获取返回值类型
			Class<?> returnType2 = method2.getReturnType();
			String simpleName2 = returnType2.getSimpleName();
			//获取参数列表
			Class<?>[] parameterTypes = method2.getParameterTypes();
			for (Class<?> class1 : parameterTypes) {
				System.out.println(class1.getSimpleName());
			}
			System.out.println(string2+" "+name2+" "+simpleName2);
		}
		
		
		System.out.println("-- getMethods(String name, Class<?>...parameterTypes) 获取本类以及父类指定的公共方法 --");
		Method method2 = cls.getMethod("show", String.class);
		//获取名称
		String name2 = method2.getName();
		//获取返回值类型
		Class<?> returnType2 = method2.getReturnType();
		String simpleName2 = returnType2.getSimpleName();
		//获取参数列表
		Class<?>[] parameterTypes = method2.getParameterTypes();
		for (Class<?> class1 : parameterTypes) {
			System.out.println(class1.getSimpleName());
		}
		System.out.println(string2+" "+name2+" "+simpleName2);
		//调用方法
		method2.invoke(goods, "wozhenshuai");
	} 
}

JavaBean转JavaBean案例
在这里插入图片描述
在这里插入图片描述

package demo6;

import java.lang.reflect.Field;

import javax.swing.text.StyledEditorKit.ForegroundAction;

/*
 * 通过反射实现JavaBean转JavaBean
 */
public class BeanToBean {
	public static void main(String[] args) throws Exception {
		//1.创建Teacher对象并赋值
		Teacher teacher = new Teacher(1,"王老师",18);
		Student student = new Student();
		
		Class<? extends Student> cls2 = student.getClass();//获取Student的一个运行时类
		Field[] declaredFields = cls2.getDeclaredFields();
		
		
		//利用反射将Teacher对象转换成Student对象
		Class<? extends Teacher> cls = teacher.getClass();//获取Teacher对象
		Field[] fields = cls.getDeclaredFields();//获取属性值
		for (Field field : fields) {//遍历所有的属性
			field.setAccessible(true);//打破封装
			String name = field.getName();//获取名称
			Object value = field.get(teacher);//获取属性的值
			Class<?> type = field.getType();//获取类型
			String simpleName = type.getSimpleName();//获取简称
			 
			for (Field field2 : declaredFields) {
				field2.setAccessible(true);
				String name2 = field2.getName();
				String simpleName2 = field2.getType().getSimpleName();
				
				//判断如果名称相同并且类型相同就将teacher对象中对象的值赋值给student 
				if (name.equals(name2)&&simpleName.equals(simpleName2)) {
					field2.set(student, value);
				}
			}
		}
		System.out.println(student);
	}
}

JavaBean转换为Map实例

package demo6;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

/*
 * 利用反射将Student对象的值,装载到Map中
 */
public class BeanToMap {
	public static void main(String[] args) throws Exception, IllegalAccessException {
		Student student = new Student(1,"san",18);
		
		Map<String, Object> map = new HashMap<String, Object>();//将Student对象装载到Map之中,Map(Key,Value),但是因为不知道有什么值,所以用Object
		Class<? extends Student> class1 = student.getClass();//获取运行时类
		Field[] declaredFields = class1.getDeclaredFields();//获取所有的属性
		for (Field field : declaredFields) {
			field.setAccessible(true);
			String key = field.getName();//获取名称
			Object value = field.get(student);//获取value值
			map.put(key,  value);//装载到map集合中
		}
		
		//遍历map集合
		Set<Entry<String, Object>> entrySet = map.entrySet();//获取map的entrySet
		Iterator<Entry<String, Object>> iterator = entrySet.iterator();//得到entrySet中的迭代器iterator
		while (iterator.hasNext()) {
			Entry<String, Object> next = iterator.next();
			Object value = next.getValue();
			String key = next.getKey();
			System.out.println(key+":"+value) ;
		}
	}
}

Map转换为JavaBean

package demo6;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

/*
 * 利用反射实现Map转JavaBean
 */
public class MapToBean {
	public static void main(String[] args) throws Exception {
		//1.创建Map集合,向集合中添加K-V(要求key要与JavaBean中属性名称对应)
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", 2);
		map.put("name", "hong");
		map.put("age", 12);
		
		Student student = new Student();
		
		Class<? extends Student> class1 = student.getClass();//获取运行时类
		Field[] declaredFields = class1.getDeclaredFields();//获取运行时类的属性
		for (Field field : declaredFields) {
			field.setAccessible(true);//打破封装
			String name = field.getName();//获取属性名称
			
//			-------------------遍历Map集合--------------------------
			Set<Entry<String, Object>> entrySet = map.entrySet();
			Iterator<Entry<String, Object>> iterator = entrySet.iterator();
			while (iterator.hasNext()) {
				Entry<String, Object> next = iterator.next();
				Object value = next.getValue();
				String key = next.getKey();  
				
				if (name.equals(key)) {
					field.set(student, value);
				}
			}
		}
		//属性JavaBean对象,验证是否转换成功
		System.out.println(student);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值