java的反射可以绕过访问权限,访问到类的私有方法和成员。可能这点会引起安全性的讨论。反射的使用帮助解决很多复杂的问题,其运行时的类型检查,动态调用,代理的实现等,反射为我们写程序带来了很大的灵活性,很多功能都是基于反射。
利用反射还可以访问内部类、匿名内部类的私有属性。
用java自带的java -private 类名 反编译命令可以查看类的完整定义。(参考think in java)
下面举例子说明。首先定义一个接口
public interface Ref {
public void f();
}
接口的实现类
public class RefImpl implements Ref {
//实现接口方法
public void f() {
System.out.println("public method f()");
}
void g(String args){
System.out.println("package method g():" + args);
}
private void w(){
System.out.println("private method w()");
}
}
测试类
public class TestRef {
public static void main(String[] args) {
Ref ref = new RefImpl();
System.out.println(ref.getClass().getSimpleName()); //RefImpl类型
ref.f(); //调用接口方法
// ref.g(); //向上转型后实现类添加的方法不能调用
if(ref instanceof RefImpl){
RefImpl ref1 = (RefImpl)ref; //类型识别后转型
ref1.g("zhouyang");
// ref1.w(); //私有方法不能访问
}
//通过反射调用方法
try {
Ref ref2 = new RefImpl();
Method m = ref2.getClass().getDeclaredMethod("f");
Method m1 = ref2.getClass().getDeclaredMethod("g", String.class);//有参的方法
Method m2 = ref2.getClass().getDeclaredMethod("w");
System.out.println("==============");
m.invoke(ref); //调用方法f()
m1.invoke(ref, "yangzhou");
m2.setAccessible(true);///调用private方法的关键一句话
m2.invoke(ref);
} catch (Exception e) {
e.printStackTrace();
}
//java的javap反编译能够查看类的信息,-private 开关能够打开所有信息
//javap -private 类名 类必须是编译成.calss 文件
//利用反射访问私有成员,改变私有成员值,但是final域可以访问不可改变
PrivateField pf = new PrivateField();
// ps.ss; //私有成员不能访问
//打印原来的成员值
pf.print();
try {
//反射访问和改变原来值
Field[] f = pf.getClass().getDeclaredFields();
for(int i=0;i<f.length;i++){
f[i].setAccessible(true);
System.out.println(f[i].getType());//打印字段类型
System.out.println(f[i].get(pf)); //打印值
if("ss".equals(f[i].getName())){
f[i].set(pf, "hehe"); //修改成员值
}else{
f[i].setInt(pf, 55);
}
}
//重新打印修改后的成员值,final域值不变
pf.print();
} catch (Exception e) {
e.printStackTrace();
}
/*打印输出的结果
* RefImpl
public method f()
package method g():zhouyang
==============
public method f()
package method g():yangzhou
private method w()
ss:nihao
count:1
num:47
class java.lang.String
nihao
int
1
int
47
ss:hehe
count:55
num:47
*/
}
}
class PrivateField {
private String ss = "nihao";
private int count = 1;
private final int num = 47;
void print(){
System.out.println("ss:" + ss);
System.out.println("count:" + count);
System.out.println("num:" + num);
}
}
分享到:
相关推荐
总结来说,Java反射机制是Java编程中的一种高级技术,主要用于动态加载类、创建对象、访问和修改私有成员、调用私有方法等。在设计和实现某些复杂或高度灵活的系统时,反射机制能够发挥关键作用,但应谨慎使用,避免...
成员方法用于定义对象的行为,可以是任何公共或私有的方法。 **This关键字:** This关键字代表当前对象的引用,可以用来访问当前对象的属性和方法。 **访问控制符:** Java中有四种访问修饰符:public、...
在chapter28的代码中,可能会看到如何通过反射创建对象、调用方法、访问和修改私有属性等。 综上所述,这个章节的课后习题旨在通过实践加深对Java高级特性的理解,提高编程能力。通过解这些习题,开发者能更好地...
1. **集合框架**:Java集合框架是Java中用于存储和操作对象的核心组件。它包括List(如ArrayList和LinkedList)、Set(如HashSet和TreeSet)和Map(如HashMap和TreeMap)接口,以及对应的实现类。工具类库可能会提供...
- 反射API允许在运行时检查类的信息,创建和操作对象,调用私有方法,甚至修改类的字段。 - Class类:代表Java类的运行时信息。 - 构造器、方法和字段的反射调用。 7. **对象拷贝** - 浅拷贝:仅复制对象的引用...
- 私有属性访问:`Field field = clazz.getDeclaredField("fieldName"); field.setAccessible(true);` #### 八、泛型 - **概念** - 泛型提供了一种类型安全的机制来处理不同类型的对象集合。 - 示例:`List...
`static`关键字用于声明成员变量和成员方法的共享性。它具有以下特点: - **静态变量**:也称为类变量,由类的所有实例共享。可以通过类名直接访问。 - **静态方法**:没有当前对象的概念,因此不能访问实例变量。...
在Android开发中,反射常用于动态调用私有方法、访问私有变量、处理兼容性问题等。 - 关键API:`Class.forName()`、`getMethod()`、`getField()`、`invoke()`等。 4. **屏幕相关**: - 屏幕尺寸、分辨率的适配是...
集合框架是Java中用于存储和操作对象的工具,包括List(ArrayList、LinkedList)、Set(HashSet、TreeSet)和Map(HashMap、TreeMap)等接口及其实现类。 6. **输入输出流** Java提供了丰富的I/O流类库,用于读写...
- 集合是Java中用于存储和操作对象的一种数据结构。 - 主要有List、Set、Map三种类型。 - **IO流** - IO流用于处理输入输出操作。 - 包括文件读写、网络通信等。 - **多线程** - 多线程允许程序同时执行多个...
- **方法**:方法是Java中用来执行特定功能的代码块。 - **流程控制语句**:如if-else、switch-case、for循环等,用于控制程序的执行流程。 - **IDEA与Eclipse**:常用的Java集成开发环境(IDE),提供代码编辑、...
2.2.3. 本地方法区(线程私有) ................................................................................................................ 23 2.2.4. 堆(Heap-线程共享)-运行时数据区 .....................