概念:
在运行状态中在仅知道一个类名时,就可以动态获得类中信息,创建对象,调用对象成员机制,称为java反射机制
在学习框架之前使用java类的方法
● 已知一个类的类名、以及、类中的方法属性、构造方法等
● 使用new关键字创建对象
● 使用对象调用方法或属性
Java反射的作用
• 动态获取类的信息。
如何获得类的class对象
1.通过Class类的静态方法forName
java
String classname ="com.wph.javaReflect.User";
Class clazz1 = Class.forName(classname);
System.out.println(clazz1);
2.通过运行时类的属性
java
String classname ="com.wph.javaReflect.User";
//方式2:
Class clazz2=User.class;
3.调用getClass()
java
String classname ="com.wph.javaReflect.User";
User user=new User();
Class clazz3= user.getClass();
如何获得获得Constructor类(构造方法)
1.Constructor getConstructor(Class... parameterTypes) :
通过指定参数类型,返回构造方法实例。
2.Constructor类可以通过getXXX方法获得构造方法的基本信息.
3.getName:返回构造方法的名字
4.除了获得构造方法的基本信息,还可以创建实例 newInstance(Object... initargs) :创建实例
java
String classname="com.wph.javaReflect.User";
//1.通过类名获得类的class对象
Class aClass=Class.forName(classname);
//2.通过类的CLass对象,创建对象
Object object=aClass.newInstance();
System.out.println(object);
//获得类中的构造方法,通过构造方法api中的方法创建对象
Constructor constructor=aClass.getConstructor();//获得指定的公共构造方法
Object object1=constructor.newInstance();//创建对象
Constructor constructor1=aClass.getConstructor(String.class,String.class);
Object object2=constructor1.newInstance("zhangsan","1111");
Constructor [] constructors=aClass.getConstructors();//获得所有公共的构造方法
System.out.println(constructors.length);
/* aClass.getDeclaredConstructor();//获得类中任意构造方法,包含私有
aClass.getDeclaredAnnotations();//获得类中所有构造方法*/
如何获得获得Field(成员变量)
1.public Field getField(String name)通过指定Field名字,返回 Field实例.
2.Field类将类的属性进行封装,可以获得属性的基本信息、属性的值,也 可以对属性进行赋值.
java
String classname="com.wph.javaReflect.User";
//1.通过类名获得类的class对象
Class aClass=Class.forName(classname);
Object object=aClass.newInstance();
// Field accountField = aClass.getField("account");//获得指定名称的公共成员变量
/*
Field accountField= aClass.getDeclaredField("account");//获得指定名称的成员变量,包含私有的
accountField.setAccessible(true);
accountField.set(object, "admin");
System.out.println(object);*/
HashMap<String,String> map=new HashMap<String, String>();
map.put("account", "admin");
map.put("Password", "1111");
Field[] declaredFields = aClass.getDeclaredFields();
for(Field field:declaredFields){
field.setAccessible(true);
field.set(object,map.get(field.getName()));
}
System.out.println(object);
}
如何获得获得Method(类中的方法)
1.Method getMethod(String name, Class... parameterTypes) : 通过指定方法名,参数类型,返回一个Method实例
2.getName:获得方法名字
- getParameterTypes:获得方法参数类型 ●
4.除了动态获得方法信息外,Method还能动态调用某一个对象的具体方法 ●
5.invoke(Object obj, Object... args) :使用obj调用该方法,参数为args
java
String classname="com.wph.javaReflect.User";
//1.通过类名获得类的class对象
Class aClass=Class.forName(classname);
Object object=aClass.newInstance();
HashMap<String,String> map=new HashMap<String, String>();
map.put("account", "admin");
map.put("password", "1111");
//先拿到类中所有的私有属性
Field[] declaredFields = aClass.getDeclaredFields();
for(Field field : declaredFields){
//根据属性名 生成set方法名称
String setmethod= "set"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
//通过Class对象,获得对应的set方法对象
Method setmethodObj = aClass.getMethod(setmethod, field.getType());
//调用set方法
setmethodObj.invoke(object,map.get(field.getName()));
}
System.out.println(object);
}
反射案例
自定义java对象转json工具类
java
package com.wph.javaReflect;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class jsonutil {
public static String objectToJson(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class clazz=object.getClass();
String json="{";
Field[] declaredFields =clazz.getDeclaredFields();
for(Field field : declaredFields) {
//生成属性get方法名字
String getmethod = "get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
//获得方法对象
Method method=clazz.getMethod(getmethod );
//调用方法
Object value=method.invoke(object);
//把属性名和值拼接成键值
json+=field.getName()+":"+value+",";
}
json=json.substring(0,json.length()-1);//去掉多余逗号
json+="}";
return json;
}
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
User user=new User();
user.setAccount("admin");
user.setPassword("1111");
Car car=new Car();
car.setName("bm");
car.setColor("red");
System.out.println(jsonutil.objectToJson(user));
System.out.println(jsonutil.objectToJson(car));
}
}
反射优缺点
● 优点:
1.增加程序的灵活性,可以在运行的过程中动态对类进行修改和操作
2.提高代码的复用率,比如动态代理
3.可以在运行时轻松获取任意一个类的方法、属性,并且还能通过反射进行动态 调用
缺点:
1.反射会涉及到动态类型的解析,导致性能要比非反射调用更低
2.使用反射技术通常要在一个没有安全限制的程序运行.
3.反射可以绕过一些限制访问的属性或者方法,可能会导致破坏代码本身的抽象 性
总结
AVA反射机制是在运行状态中,对于任意一个类,都能够知道这个 类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个 方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为 java语言的反射机制。