下例演示了通过反射获取 Test 类对象 t 的 iVal, strVal 成员变量的值:
import javalangreflectField;class Test {
private int iVal;
private String strVal;
public Test(int iVal, String strVal) {
thisiVal = iVal;
thisstrVal = strVal;
}
}
public class App {
public static void main(String[] args) {
// 创建一个 Test 对象
Test t = new Test(123, "Hello");
// 获取对象 t 的 Class
Class<> tt = tgetClass();
try {
// 获取 Test 类的 iVal 字段 Field
Field field = ttgetDeclaredField("iVal");
// 设置可访问
fieldsetAccessible(true);
// 获取 iVal 的值
int val = fieldgetInt(t);
Systemoutprintln(val);
Field strValField = ttgetDeclaredField("strVal");
strValFieldsetAccessible(true);
String strVal = (String)strValFieldget(t);
Systemoutprintln(strVal);
} catch (NoSuchFieldException | SecurityException e) {
eprintStackTrace();
} catch (IllegalArgumentException e) {
eprintStackTrace();
} catch (IllegalAccessException e) {
eprintStackTrace();
}
}
}
package reflection;
import javalangreflectField;
import javalangreflectMethod;
/
该类主要练习使用java的反射机制调用其他类的
private方法和变量;
/
public class MethodTest
{
public static void main(String[] args) throws Exception
{
Class<> classType = Peopleclass;
People p1 =(People) classTypenewInstance();
// 获取指定的方法,调用People类的私有方法;
Method method = classTypegetDeclaredMethod("sayHello",
new Class[] { Stringclass });
methodsetAccessible(true);//压制java的访问修饰符;
methodinvoke(p1, new Object[]{"Mr zhou"});
//获取People类的私有属性;
Field field = classTypegetDeclaredField("age");
fieldsetAccessible(true);
fieldset(p1, 12);
Systemoutprintln(fieldget(p1));
}
}
class People
{
private int age;
private String name;
public int getAge()
{
return age;
}
public void setAge(int age)
{
thisage = age;
}
public String getName()
{
return name;
}
public void setName(String name)
{
thisname = name;
}
private void sayHello(String str)
{
Systemoutprintln("Hello: " + str);
}
}
这里用的是一个单件模式,
GetProvider()这个方法,用来生成一个IDataProvider接口的实例化对象,中间应用了反射方法,下面这行:
instance = (IDataProvider)ActivatorCreateInstance(TypeGetType(stringFormat("MusicData{0}DataProvider,MusicData{0}", ConfigsGetDbType), false, true));
调用反射创建满足接口IDataProvider的类,赋给instance。类似于平常编写的IdataProvider instance=new MusicDataAccessDataProvider();这种方式。但应用反射的方式,这样使代码更容易配置,更加灵活。如这里,可以创建多种数据库的访问方式,实现IDataProvider,然后在配置文件中写入当前应用的数据库类名信息,就可以通过反射创建具体的类。上面那句的ConfigsGetDbType用来获取当前配置文件中的当前数据库信息,返回的是你填写的信息,如SqlServer、Access、MySql,具体代码我看不到,但原理是这样的。
你填写的信息应该满足:
MusicData命名空间DataProvider
也就是比如你有一个Access数据访问方式
你应该新建一个类库:格式为
namespace MusicData命名空间
{
class DataProvider:IDataProvider
{
//这个类必须实现IDataProvider接口
}
}
注意:命名空间你替换成你的,比如Access,SqlServer等
这个类库生成的dll你应该命名成 MusicData命名空间dll 命名空间就是你配置文件的标识,你配置文件中填写你上面定的命名空间就行了。
又如,你还有一个SqlServer方式访问的数据库:
那么新建类库
namespace MusicDataSqlServer
{
class DataProvider:IDataProvider
{
//这个类必须实现IDataProvider接口
}
}
生成dll为MusicDataSqlServerdll
如果还有其他数据库访问途径,类似方法
建其他的类库
配置文件中写上Access/SqlServer或者其他,
要和你的命名空间保持一致。因为反射时是根据命名空间+类名的方式创建对象的,如代码中的:
TypeGetType(stringFormat("MusicData{0}DataProvider,MusicData{0}", ConfigsGetDbType)
里面的字符串就是你要创建的类的完整名字:
格式为:
TypeGetType("类完整名,程序集名");
类完整名=命名空间名+类名
下面的方法:
IDataProvider GetInstance()
就是使用单件模式,获取一个IDataProvider
里面使用了锁,防止多线程同时进行时冲突,这里面进行了判断,如果_instance为空就用上面的函数创建一个新的,然后返回。
最后一个方法是释放对象。
有时间去网上搜点反射方面的例子,单件模式应该很容易看懂的,就是用一个静态私有变量,只保持一个实例对象_instance存在。
建议研究一下PetShop源代码,然后关于三层和反射工厂就会有一个新的认识。
最近需要些一个可配置的索引构建程序 需要在运行时调用Lucene包的如下类及其成员
引用
Nested Class Summary
static class Field Index
Specifies whether and how a field should be indexed
static class Field Store
Specifies whether and how a field should be stored
static class Field TermVector
Specifies whether and how a field should have term vectors
lucene api中称之为Nested Class 意为嵌套类 而嵌套类内部的File Index的成员又是静态成员
引用
Field Summary
static Field Index ANALYZED
Index the tokens produced by running the field s value through an Analyzer
static Field Index ANALYZED_NO_NORMS
Expert: Index the tokens produced by running the field s value through an Analyzer and also separately disable the storing of norms
static Field Index NO
Do not index the field value
static Field Index NO_NORMS
Deprecated This has been renamed to NOT_ANALYZED_NO_NORMS
static Field Index NOT_ANALYZED
Index the field s value without using an Analyzer so it can be searched
static Field Index NOT_ANALYZED_NO_NORMS
Expert: Index the field s value without an Analyzer and also disable the storing of norms
static Field Index TOKENIZED
Deprecated this has been renamed to ANALYZED
static Field Index UN_TOKENIZED
Deprecated This has been renamed to NOT_ANALYZED
一个棘手的问题 如果获得这些内部静态成员?
最后采用了如下方法
//运行时调用Filed Index类型
Java代码
Class<> cls = apache lucene document Field Index class;
java lang reflect Field indexDeclareField = cls getDeclaredField(field getIndex());
Object indexDeclareFieldType = indexDeclareField get(cls);
apache lucene document Field Index filedIndex = ( apache lucene document Field Index)indexDeclareFieldType;
//运行时调用Field Store类型
Class<> clsStore = apache lucene document Field Index class;
java lang reflect Field storeDeclareField = cls getDeclaredField(field getIndex());
Object indexStoreDeclareField = indexDeclareField get(cls);
lishixinzhi/Article/program/Java/hx/201311/26078
用反射可以得到
如果只需要静态变量可以通过xgetModifiers()来判断
import javalangreflectField;
class A{
public static int a = 4;
public static int b = 5;
private static int c = 6;
}
class C{
public static void main(String args[]) throws Exception{
Class x = Aclass;
//我想用x来得到静态变量的值,请不要为我想别的其他办法,这只是个示例程
//序,我的程序要把Class 的x当传参,A也是多态的,必须要用x得到静态变量。
Field[] fields = xgetDeclaredFields();
for(int i=0;i<fieldslength;i++){
fields[i]setAccessible(true);
if((fields[i]getModifiers() & 8) == 8){
Systemoutprintln(fields[i]get(null));
}
}
}
}
这是一个很值得探讨的问题,许多人接触反射时,对反射功能之强大都会抱有怀疑,感觉严重破坏了封装的性质。可是,什么是封装,什么是安全呢?
封装,是将具体的实现细节隐藏,而把功能作为整体提供给类的外部使用,也就是说,公有方法能够完成类所具有的功能。当别人使用这个类时,如果通过反射直接调用私有方法,可能根本实现不了类的功能,甚至可能会出错,因此通过反射调用私有方法可以说是没有任何用处的,开发人员没有必要故意去破坏封装好的类。从这点上看,封装性并没有被破坏。
所谓安全,如果意思是保护实现源码不被别人看见,那没有作用。不用反射也能轻易获取源码。
所以我以为反射机制只是提供了一种强大的功能,使得开发者能在封装之外,按照特定的需要实现一些功能。就好比核技术,虽然造核d很危险吧,但造核电站还是很有用处的(这个比喻似乎不是很恰当,将就将就)。
曾经给朋友讨论过这个问题,感觉解释得不是很清楚,大家一起探讨探讨,看看怎样表述才能更容易理解:)
以上就是关于大佬告诉我java 反射如何获取成员变量的值全部的内容,包括:大佬告诉我java 反射如何获取成员变量的值、java 如何调用一个私有方法里的私有成员变量、public static IDataProvider GetInstance()等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)