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