大佬告诉我java 反射如何获取成员变量的值

大佬告诉我java 反射如何获取成员变量的值,第1张

下例演示了通过反射获取 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()等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9846076.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-02
下一篇 2023-05-02

发表评论

登录后才能评论

评论列表(0条)

保存