java反射问题
如何反射取到对象中的一个属性,这个属性是一个对象来的。。。那如果取到这个对象是空的话那怎么去创建它是;比如:
public class Test1(){
}
public class Test2(){
private Test1 test1;
public String getStr() {
return test1;
}
public void setStr(Test1 test1) {
this.test1= test1;
}
}
就比如反射Test2取到test1然后创建test1让它不为空对象 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 是要这效果?
package org.hilo;--------------------编程问答--------------------
import java.lang.reflect.Method;
public class Test2 {
private Test1 test1;
public Test1 getTest1() {
return test1;
}
public void setTest1(Test1 test1) {
this.test1 = test1;
}
public static void main(String[] args) throws Exception {
Test2 test2 = new Test2();
Method m1 = test2.getClass().getMethod("getTest1");
//反射执行Test2类的getTest1方法
Object obj = m1.invoke(test2);
//如果对象为空,则设值
if(obj == null){
Method m2 = test2.getClass().getMethod("setTest1", Test1.class);
m2.invoke(test2, new Test1("这是后来的对象"));
}
obj = m1.invoke(test2);
if(obj != null){
Test1 test1 = (Test1)obj;
System.out.println(test1);
}
}
}
class Test1 {
private String test;
public Test1(String _test) {
test = _test;
}
@Override
public String toString() {
return test;
}
}
这样子做是可以。。但我想要的效果不是这样子的if(obj != null){
Test1 test1 = (Test1)obj;
System.out.println(test1);
}。。。我想要的是直接取到通过反射取到test1判断它是一个对象然后它是空的话就通过反射来创建它 --------------------编程问答-------------------- package Reflect;
/**
* 通过一个对象获得完整的包名和类名
* */
class Demo{
//other codes...
}
class hello{
public static void main(String[] args) {
Demo demo=new Demo();
System.out.println(demo.getClass().getName());
}
}
【运行结果】:Reflect.Demo --------------------编程问答-------------------- 加个判断 getDeclaredField(test1).get(Test2) == null --------------------编程问答--------------------
Demo demo=new Demo();你是自己知道这个对象。然后创建出来的。。想想在一个实体里面还包含另一个实体那我们要怎么写才能让系统知道这是一个对象并让它通过反射创建出来,而并不是说我们自己知道这是一个对象并通过NEW出来在放进去,,,就像Hibernate一样可以有很多的关连关系,和它有关连的实只要有数据就不会是空,也就是可以创建它的关连对象出来。它肯定不能现我们那样子做做的。。 --------------------编程问答-------------------- hibernate,struts2容器,spring这些框架构建对象都有通过xml配置,他们通过读取xml信获取这个对象的class。
--------------------编程问答-------------------- hibernate是根据xml配置或者注解知道这个对象是否是有关联关系的如果有关联关系的自然会知道是对象还是数组或是集合。我这里就不根据xml或是注解标识了,直接取出属性类型,只要不是基本数据类型,集合,数组,枚举,以及基本数据类型的封装类型的那么就是对象了
--------------------编程问答--------------------
Test2 test2=new Test2();
//获取javaBean的bean信息
BeanInfo beanInfo=Introspector.getBeanInfo(test2.getClass(),Object.class);
//获取javaBean中所有的属性描述只要带set get方法的都能得到
PropertyDesciptor[] pds=beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd:pds){
//获得属性的类型
Class<?> clazz=pd.getPropertyType;
//满足不是基本数据类型,不是数字类型的封装类型,不是字符串不是boolean类型的封装类型的就是对象了
if(!clazz.isPrimitive()&&!Number.class.isAssignableFrom(clazz)&&clazz!=String.class&&clazz!=Boolean.class&&Collection.class.isAssignableFrom(clazz)&&!
clazz.isArray()&&!clazz.isEnum()){
//是对象的判断是否为空
Method readMethod=pd.getReadMethod();//获取此属性的读方法(get方法)
//在test2对象上调用此属性的get方法获取此属性的值
Object obj=readMethod.invoke(test2});
if(obj==null){//如果是null就创建
obj=clazz.newInstance();
}
}
public class TestReflectObj {
public static Object reflectCreateObj(Class cls) {
Object descObj = null;
try {
descObj = cls.newInstance();
Field[] fields = cls.getDeclaredFields();
for (int i=0; i<fields.length; i++) {
if (fields[i].get(descObj) == null) {//如果属性为null,就嵌套实例化
fields[i].set(descObj, reflectCreateObj(fields[i].getType()));
}
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
return descObj;
}
public static void main(String[] args) {
RA ra = (RA) reflectCreateObj(RA.class);
System.out.println(ra.rb.rb);
}
}
class RA {
public String ra = "ra";
public RB rb;
}
class RB {
public String rb = "rb";
}
这样是不是你想要的效果呢?
我不太清楚你的需求是什么。如果是要深度复制的话,还是用序列化反序列化比较简单。
private static Object depthClone(Object srcObj){
74. Object cloneObj = null;
75. try {
76. ByteArrayOutputStream out = new ByteArrayOutputStream();
77. ObjectOutputStream oo = new ObjectOutputStream(out);
78. oo.writeObject(srcObj);
79.
80. ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
81. ObjectInputStream oi = new ObjectInputStream(in);
82. cloneObj = oi.readObject();
83. } catch (IOException e) {
84. e.printStackTrace();
85. } catch (ClassNotFoundException e) {
86. e.printStackTrace();
87. }
88. return cloneObj;
89. }
希望可以帮到你。。 --------------------编程问答-------------------- web项目的前台jsp取值???
你可能想做一个通用的?但是你这里只有一个子类,,,如果有多个呢? 那估计更复杂,,通用很难,,而且根据你的想法,你根本不可能获取到子类。。。。。。。
补充:Java , Java EE