反射指的是对对象的反向处理操作,没有反射,就没有Java中的任何框架。
通过反射,可以取得对象身后的组成,例如(类、构造方法、普通方法、成员)。
为了实例化类,我们先要取得Class类的对象,即类名。
取得Class实例化对象有以下三种方法: ① Class类对象。getClass()。
② 类名。class
③ class.forName(String className)
取得了Class实例化对象,我们就可以用反射实例化对象 。方法是 Class实例化对象。newInstance()。
使用以上提供反射的方法,可以写一个简单的反射工厂设计模式:
package test;
interface friut{
public void eat();
}
class Orange implements friut{
public void eat() {
System.out.println("吃橘子");
}
}
class apple implements friut{
public void eat() {
System.out.println("吃苹果");
}
}
class Factory{
public static friut getInstance(String className) throws InstantiationException, IllegalAccessException {
friut friut=null;
try {
Class<?> cls = Class.forName(className);
cls = Class.forName(className);
friut=(friut)cls.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return friut;
}
}
public class Test {
public static void main(String[] args) throws Throwable, IllegalAccessException {
friut friut=Factory.getInstance("test.Orange");
friut.eat();
}
}
反射实现工厂设计模式的好处是,每当新增接口子类,无需修改工厂类代码就可以方便的进行接口子类的扩容了。
反射可以取得对象中你所需要的一切,例如:方法,父类信息,属性等等。
取得父类信息: 取得包名: Class类对象。getPackage().getName();
取得父类名称: Class类对象。getSuperclass().getName();
取得方法: 取得指定参数构造方法: Class类对象.getConstructor(参数类型以及个数)
import java.lang.reflect.Constructor;
class person{
private String name;
private int age;
public person (String name,int age) {
this.name=name;
this.age=age;
}
public String toString() {
return name+age;
}
}
public class Test {
public static void main(String[] args) throws Exception {
Class<?>cls=person.class;
Constructor<?>cons=cls.getConstructor(String.class, int.class);
person person=(person) cons.newInstance("human",20);
System.out.println(person);
}
}
取得所有构造方法:Class类对象.getConstructors();
处理取得构造方法,还可以取得普通方法:
取得全部普通方法:Class类对象.getMethods();
取得指定普通方法:Class类对象.getMethod(方法名,方法参数);
取得了方法以后,我们可以通过invoke来调用方法 :方法对象.invoke(类实例化对象,方法具体参数)。
例如:
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
class Person{
private String name;
private int age;
public Person(String name){
this.name=name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString(){
return "Person="+name+","+"age="+age;
}
}
public class Test {
public static void main(String[] args) throws Exception {
Class<?>cls=Person.class;
Constructor<?> constructor=cls.getDeclaredConstructor(String.class);
Person person=(Person) constructor.newInstance("higher");
Method setMethod=cls.getMethod("setAge", int.class);
setMethod.invoke(person, 45);
System.out.println(person);
}
}
反射还可以调用类中属性:
取得类中全部属性: Class对象。getFilds()。
取得类中指定名称属性: Class对象。getFild(属性名称)。
例如:
import java.lang.reflect.Field;
class Person{
private String name;
public int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) throws Exception {
//1.取得class对象
Class<?> cls=Person.class;
//2.取得具体类实例化对象
Person person=(Person)cls.newInstance();
//3.取得Field对象
Field field=cls.getField("age");
//4.设置以及取得属性
field.set(person, 40);
//Object object=field.get(person);
System.out.println(field.get(person));
}
}
至此,反射中的相关操作就已经介绍完毕了,通过以上反射调用的方法,我们可以用反射操作VO。
设计一个反射操作VO,输入字符串,统一设置属性值:
public class Test {
public static void main(String[] args) throws Exception {
String value="emp.name:superman|emp.job:Java coder";
EmpAction empAction=new EmpAction();
empAction.setValue(value);
System.out.println(empAction.getEmp());
}
}
public class Emp {
private String name;
private String job;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
@Override
public String toString() {
return "Emp [name=" + name + ", job=" + job + "]";
}
}
public class EmpAction {
private Emp emp=new Emp();
public void setValue(String value) throws Exception {
BeanOperation.setBeanValue(this,value);
}
public Emp getEmp(){
return emp;
}
}
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.sun.org.apache.xml.internal.security.Init;
class BeanOperation{
private BeanOperation(){}
public static void setBeanValue(Object actionObject,String msg) throws Exception{
String[]result=msg.split("\\|");
for(int i=0;i<result.length;i++){
String[]temp=result[i].split(":");
String value=temp[1];
String []finalResult=temp[0].split("\\.");
String realClassName=finalResult[0];
String attr=finalResult[1];
Object realObject=getRealObject(actionObject, realClassName);
String realAttr=finalResult[1];
Field realField=realObject.getClass().getDeclaredField(realAttr);
String setMethodNameString="set"+initCap(realAttr);
Method setMethod=realObject.getClass().getDeclaredMethod(setMethodNameString, realField.getType());
setMethod.invoke(realObject, value);
}
}
public static Object getRealObject(Object actionObject,String realClassName) throws Exception {
Object realObject=null;
Class<?>cls=actionObject.getClass();
Field field=null;
field=cls.getDeclaredField(realClassName);
if(field==null){
field=cls.getField(realClassName);
if(field==null){
return null;
}
}
String methodName="get"+initCap(realClassName);
Method method=cls.getDeclaredMethod(methodName);
return realObject=method.invoke(actionObject);
}
public static String initCap(String str) {
return str.substring(0, 1).toUpperCase()+str.substring(1);
}
public static void setObjectvalue(Object obj,String attribute,String value) throws Exception{
Field field=obj.getClass().getDeclaredField(attribute);
if(field==null){
field=obj.getClass().getField(attribute);
}
if(field==null){
return;
}
String methodName="set"+initCap(attribute);
Method setMethod=obj.getClass().getMethod(methodName, field.getType());
setMethod.invoke(obj, value);
}
}
综合使用反射调用方法,类,属性来达到我们的需求。
1228

被折叠的 条评论
为什么被折叠?



