Java 访问类类型动态已知的对象的方法和函数
我有一个类型为A的对象A1。我动态地发现,该对象A1是类型A。我现在有一个属性,比如“Name”,我想从A1访问它,我该怎么做 现在最大的问题是,对象A1甚至可以是类型B。如果它是类型B,那么我必须获得值“Address”。现在我如何解决这个问题 下面的代码执行类型检查Java 访问类类型动态已知的对象的方法和函数,java,dynamic,classloader,Java,Dynamic,Classloader,我有一个类型为A的对象A1。我动态地发现,该对象A1是类型A。我现在有一个属性,比如“Name”,我想从A1访问它,我该怎么做 现在最大的问题是,对象A1甚至可以是类型B。如果它是类型B,那么我必须获得值“Address”。现在我如何解决这个问题 下面的代码执行类型检查 public static void testing(Object A1, String s) s - Classtype { try{ Class c = Class.forName(s)
public static void testing(Object A1, String s) s - Classtype
{
try{
Class c = Class.forName(s);
if( c.isInstance(A1)) //
{
//Now I know that A1 is of the type C. But I dont know what type 'c' is (whether type A or type B. Because Only then I can access the appropriate member.) Like I said, type A contain 'name' and type B contains address.
// The access may not only be a member but also a method .
}
}catch (Exception e){ System.out.println(e);}
}
任何指示都会很有帮助。谢谢您可以知道类的声明字段
Class cls = Class.forName("MyClass");
Field fieldlist[] = cls.getDeclaredFields();
Class cls = Class.forName("MyClass");
Field fieldlist[] = cls.getDeclaredFields();
field.setAccessible(true);
顺便说一句,你确定你真的希望在这种情况下使用反射吗?您可能考虑过声明接口吗?类(实现)仍然可以动态加载
例如:NameAccessor
和AddressAccessor
是接口
first class
和SecondClass
是类。让我们假设FirstClass
实现了NameAccessor
,而SecondClass
实现了这两个接口
现在你可以说:
Class clazz = Class.forName("SecondClass");
Object obj = clazz.newInstance();
//......
String name = ((NameAccessor)obj).getName();
String address = ((AddressAccessor)obj).getAddress();
我认为(IMHO)这种解决方案比使用反射访问私有字段要好。这些字段通常是私有的。所以,要访问它们,你必须打电话
field.setAccessible(true);
顺便说一句,你确定你真的希望在这种情况下使用反射吗?您可能考虑过声明接口吗?类(实现)仍然可以动态加载
例如:NameAccessor
和AddressAccessor
是接口
first class
和SecondClass
是类。让我们假设FirstClass
实现了NameAccessor
,而SecondClass
实现了这两个接口
现在你可以说:
Class clazz = Class.forName("SecondClass");
Object obj = clazz.newInstance();
//......
String name = ((NameAccessor)obj).getName();
String address = ((AddressAccessor)obj).getAddress();
我认为(IMHO)这种解决方案比使用反射访问私有字段要好。如果您手动执行这种操作,则会很棘手且容易出错。您应该使用几乎每个主要框架都包含的众多BeanUtils/BeanHelper类中的一个。下面是我自己的快速示例实现,如果您想:
public final class BeanHelper{
/**
* Return a map of an object's properties (key: property name, value:
* property type).
*
* @exception NullPointerException
* if bean is null
*/
public static Map<String, Class<?>> describeProperties(final Object bean){
if(bean == null){
throw new NullPointerException();
}
final Map<String, Class<?>> map;
final Class<?> beanClass = bean.getClass();
if(PROPERTIES_CACHE.containsKey(beanClass)){
map = PROPERTIES_CACHE.get(beanClass);
} else{
final PropertyDescriptor[] propertyDescriptors =
getBeanInfo(beanClass);
if(propertyDescriptors.length == 0){
map = Collections.emptyMap();
} else{
final Map<String, Class<?>> innerMap =
new TreeMap<String, Class<?>>();
for(final PropertyDescriptor pd : propertyDescriptors){
innerMap.put(pd.getName(), pd.getPropertyType());
}
map = Collections.unmodifiableMap(innerMap);
}
PROPERTIES_CACHE.put(beanClass, map);
}
return map;
}
private static PropertyDescriptor[] getBeanInfo(final Class<?> beanClass){
try{
return Introspector.getBeanInfo(beanClass, Object.class)
.getPropertyDescriptors();
} catch(final IntrospectionException e){
throw new IllegalStateException(
MessageFormat.format(
"Couldn''t access bean properties for class {0}",
beanClass),
e);
}
}
/**
* Retrieve a named property from a specified object.
*
* @return the property
* @exception NullPointerException
* if one of the arguments is null
* @exception IllegalArgumentException
* if there is no such property
*/
public static Object getBeanProperty(final Object bean,
final String property){
if(bean == null || property == null){
throw new NullPointerException();
}
final Class<?> beanClass = bean.getClass();
Map<String, PropertyDescriptor> propMap;
if(PROPERTY_DESCRIPTOR_CACHE.containsKey(beanClass)){
propMap = PROPERTY_DESCRIPTOR_CACHE.get(beanClass);
} else{
final PropertyDescriptor[] beanInfo = getBeanInfo(beanClass);
if(beanInfo.length == 0){
propMap = Collections.emptyMap();
} else{
propMap =
new HashMap<String, PropertyDescriptor>(beanInfo.length);
for(final PropertyDescriptor pd : beanInfo){
propMap.put(pd.getName(), pd);
}
}
PROPERTY_DESCRIPTOR_CACHE.put(beanClass, propMap);
}
if(!propMap.containsKey(property)){
throw new IllegalArgumentException(
MessageFormat.format(
"Class {0} does not have a property ''{1}''",
beanClass,
property));
}
return invokeMethod(propMap.get(property).getReadMethod(), bean);
}
private static Object invokeMethod(final Method method,
final Object bean,
final Object... args){
try{
return method.invoke(bean, args);
} catch(final IllegalArgumentException e){
throw e;
} catch(final IllegalAccessException e){
throw new IllegalStateException(
MessageFormat.format(
"Method not accessible: {0}",
method),
e);
} catch(final InvocationTargetException e){
throw new IllegalStateException(
MessageFormat.format(
"Error in method: {0}",
method),
e);
}
}
private static final Map<Class<?>, Map<String, Class<?>>>
PROPERTIES_CACHE =
new ConcurrentHashMap<Class<?>, Map<String, Class<?>>>();
private static final Map<Class<?>, Map<String, PropertyDescriptor>>
PROPERTY_DESCRIPTOR_CACHE =
new ConcurrentHashMap<Class<?>, Map<String, PropertyDescriptor>>();
private BeanHelper(){
}
}
public final class BeanHelper{
/**
*返回对象属性的映射(键:属性名称,值:
*属性类型)。
*
*@exception NullPointerException
*如果bean为null
*/
公共静态地图>地图;
最后一个类beanClass=bean.getClass();
if(属性\u缓存.containsKey(beanClass)){
map=PROPERTIES\u CACHE.get(beanClass);
}否则{
最终PropertyDescriptor[]propertyDescriptors=
getBeanInfo(beanClass);
如果(propertyDescriptors.length==0){
map=Collections.emptyMap();
}否则{
最终地图>();
对于(最终PropertyDescriptor pd:propertyDescriptors){
put(pd.getName(),pd.getPropertyType());
}
map=Collections.unmodifiableMap(innerMap);
}
属性\u CACHE.put(beanClass,map);
}
返回图;
}
私有静态属性描述符[]getBeanInfo(最终类beanClass){
试一试{
返回Introspector.getBeanInfo(beanClass,Object.class)
.getPropertyDescriptors();
}捕获(最终内省异常e){
抛出新的非法状态异常(
MessageFormat.format(
“无法访问类{0}的bean属性”,
beanClass),
e) );
}
}
/**
*从指定对象检索命名属性。
*
*@归还财产
*@exception NullPointerException
*如果其中一个参数为空
*@exception IllegalArgumentException
*如果没有这样的财产
*/
公共静态对象getBeanProperty(最终对象bean,
最终字符串属性){
if(bean==null | | property==null){
抛出新的NullPointerException();
}
最后一个类beanClass=bean.getClass();
地图;
if(属性\描述符\缓存.containsKey(beanClass)){
propMap=PROPERTY\u DESCRIPTOR\u CACHE.get(beanClass);
}否则{
最终属性描述符[]beanInfo=getBeanInfo(beanClass);
if(beanInfo.length==0){
propMap=Collections.emptyMap();
}否则{
propMap=
新的HashMap(beanInfo.length);
对于(最终属性描述符pd:beanInfo){
put(pd.getName(),pd);
}
}
属性\描述符\缓存.put(beanClass,propMap);
}
如果(!propMap.containsKey(属性)){
抛出新的IllegalArgumentException(
MessageFormat.format(
类{0}没有属性“{1}”,
比恩克拉斯,
财产);;
}
返回invokeMethod(propMap.get(property.getReadMethod(),bean);
}
私有静态对象调用方法(最终方法,
最终对象bean,
最终对象…args){
试一试{
invoke(bean、args);
}捕获(最终非法辩论例外e){
投掷e;
}捕获(最终非法访问例外e){
抛出新的非法状态异常(
MessageFormat.format(
“方法不可访问:{0}”,
方法),
e) );
}捕获(最终调用TargetException e){
抛出新的非法状态异常(
MessageFormat.format(
“方法{0}中有错误”,
方法),
e) );
}
}
私有静态最终M