Java反射获取内部类有局限
这周接触到继承及修改具有包访问权的内部类内容,略梳理了下各种资料,发觉在包外修改内部类内容必须通过实例.......
网上关于这部分的内容比较少,参考了下这位的帖子:http://blog.csdn.net/helloapps/article/details/5716604
反射里的Class, Field, Method, Constructor都是S物,必须结合对象使用,除非是静态的。
获取非public对象须用类似getDeclaredMethod()而不是getMethod()。
Field和Method都能设置accessible(true),之后能访问到私有权限。
这里贴的两个类,放在不同包里,能通过内部类实例修改其成员,也能使用内部类构造函数新建实例....但是还不清楚能否进一步到能修改内部类函数里的变量?
Outer class and inner class:
package ee.test1; public class OuterClass { private Inner2 inn2 = new Inner2(); public static final int PUBLIC_STATIC_NUMBER = 100;
static int DEFAULT_STATIC_NUMBER = 200;
public int PUBLIC_NUMBER = 300;
protected int PROTECTED_NUMBER = 400;
private int PRIVATE_NUMBER = 500; private String str[] = {"Str1", "Str2", "Str3"}; public Runnable ta = new Runnable() {
public void run() {
System.out.println("Method in anonymous class is executed!");
}
}; private class Inner2 {
String ta2; public Inner2() {
ta2 = "A";
System.out.println("Inner2 is instantiated!");
} public void p2() {
System.out.println("ta2: " + ta2);
}
} class Inner3 {
public Inner3() {
System.out.println("Inner2 is instantiated!");
}
} public class Inner1 {
public Inner1() {
System.out.println("Inner1 is instantiated!");
}
}
}
Test:
package ff.test2; import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import ee.test1.OuterClass; public class ReflectInnerTest { public static void main(String args[]) {
OuterClass ric = new OuterClass();
try {
reflectInner(ric);
} catch (Exception e) {
e.printStackTrace();
}
} private static void reflectInner(OuterClass ric)
throws InstantiationException, IllegalAccessException,
SecurityException, NoSuchMethodException, IllegalArgumentException,
InvocationTargetException, ClassNotFoundException,
NoSuchFieldException {
Class<? extends OuterClass> clazz = ric.getClass(); // anonymous class has NO constructor, cannot create instant or access
// method
// but could access the method and member as follows:
Runnable r = (Runnable) (clazz.getField("ta").get(ric));
r.run(); // Below to access inner class via its member.
Field f2 = clazz.getDeclaredField("inn2");
f2.setAccessible(true);
Class<?> cls = f2.getType();
Field f3 = cls.getDeclaredField("ta2");
f3.setAccessible(true);
Method m2 = cls.getDeclaredMethod("p2", null);
m2.setAccessible(true);
// f2.get(ric) (== ric.inn2) is to get the inn2 instant(which is Outer's
// member)
m2.invoke(f2.get(ric), null); // get original value
f3.set(f2.get(ric), "C"); // change it at run-time
m2.invoke(f2.get(ric), null); // show the value again Field field1 = clazz.getDeclaredField("PUBLIC_STATIC_NUMBER");
field1.setAccessible(true);
System.out.println(field1.getInt(null)); Field field2 = clazz.getDeclaredField("DEFAULT_STATIC_NUMBER");
field2.setAccessible(true);
System.out.println(field2.getInt(null)); Field field3 = clazz.getDeclaredField("PUBLIC_NUMBER");
field3.setAccessible(true);
System.out.println(field3.getInt(ric)); Field field4 = clazz.getDeclaredField("PROTECTED_NUMBER");
field4.setAccessible(true);
System.out.println(field4.getInt(ric)); Field field5 = clazz.getDeclaredField("PRIVATE_NUMBER");
field5.setAccessible(true);
System.out.println(field5.getInt(ric)); Field field6 = clazz.getDeclaredField("str");
field6.setAccessible(true);
System.out.println(((String[]) field6.get(ric))[0]);
System.out.println(Array.get(field6.get(ric), 1)); // ----------------------------------------
// Below gets the array of inner classes
Class<?> classes[] = clazz.getDeclaredClasses();
for (Class<?> c : classes) {// Reflect on member classes
int i = c.getModifiers();
String s = Modifier.toString(i);
if (s.contains("static"))// handle static inner class
c.getConstructor().newInstance();
else {
// instantiate inner classes
Constructor cons = c.getDeclaredConstructor(ric.getClass());
cons.setAccessible(true);
Object c1 = cons.newInstance(ric);
if (c.getSimpleName().equals("Inner2")) {
Method m = c.getDeclaredMethod("p2", null);
m.setAccessible(true);
m.invoke(c1, null);
Field f = c.getDeclaredField("ta2");
f.setAccessible(true);
f.set(c1, "B");
m.invoke(c1, null);
}
}
}
// -------------------------------------------------
}
}
Java反射获取内部类有局限的更多相关文章
- Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别
Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别 在工作中遇到一个问题,就是你需要去判断某个字符串是不是对象的某个成员属性名,然后根据判断结果 ...
- Java反射获取class对象的三种方式,反射创建对象的两种方式
Java反射获取class对象的三种方式,反射创建对象的两种方式 1.获取Class对象 在 Java API 中,提供了获取 Class 类对象的三种方法: 第一种,使用 Class.forName ...
- java反射获取注解并拼接sql语句
先建两个注解 分别为 Table 和 Column package com.hk.test; import java.lang.annotation.ElementType; import java. ...
- Java反射获取泛型类型
本文链接:https://blog.csdn.net/hongxingxiaonan/article/details/49202613 在Java反射技术的应用中,取得一个类的成员.方法和构造函数相对 ...
- Java 反射获取私有方法
通常我们创建一个类时,它的私有方法在类外是不可见的,但是可以通过反射机制来获取调用.具体的反射机制的介绍大家自己百度. 所以反射可能会破坏我们的单例模式,当然解决方案也是有的,就是做个标记记录次数,第 ...
- java反射获取和设置实体类的属性值 递归所有父类
最近做一个通用数据操作接口,需要动态获取和设置实体类的属性值,为了通用实体做了多重继承,开始网上找到代码都不支持父类操作,只能自己搞一个工具类了,此工具类可以设置和获取所有父类属性,代码贴下面拿走不谢 ...
- java反射获取Object的属性和值
在看反射顺便做个笔记,目前知道的反射的Object都是要有对象的也就是实体Bean. import java.lang.reflect.Field; import java.util.ArrayLis ...
- Java 反射 -- 获取泛型类型
先写一个类: public class Demo03 { public void test01(Map<String, User> map, List<User> list) ...
- Java反射获取类和对象信息全解析
反射可以解决在编译时无法预知对象和类是属于那个类的,要根据程序运行时的信息才能知道该对象和类的信息的问题. 在两个人协作开发时,你只要知道对方的类名就可以进行初步的开发了. 获取类对象 Class.f ...
随机推荐
- LA 4329 - Ping pong 树状数组(Fenwick树)
先放看题传送门 哭瞎了,交上去一直 Runtime error .以为那里错了. 狂改!!!!! 然后还是一直... 继续狂改!!!!... 一直.... 最后发现数组开小了.......... 果断 ...
- 【Codeforces Round #440 (Div. 2) B】Maximum of Maximums of Minimums
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] k=1的时候就是最小值, k=2的时候,暴力枚举分割点. k=3的时候,最大值肯定能被"独立出来",则直接输出最 ...
- SpringBoot日志logback-spring.xml分环境(转)
springboot按照profile进行打印日志 log4j logback slf4j区别? 首先谈到日志,我们可能听过log4j logback slf4j这三个名词,那么它们之间的关系是怎么样 ...
- css3-13 如何改变文本框的轮廓颜色
css3-13 如何改变文本框的轮廓颜色 一.总结 一句话总结:outline使用和border很像,几乎一模一样,多了一个offset属性 1.轮廓outline如何使用? 使用和border很像, ...
- 2. pushd . :将当前文件夹压入栈,使用popd能够回到该文件夹。
1.man -t ls | ps2pdf -> ls.pdf生成pdf格式的ls帮助文件. 2. pushd . :将当前文件夹压入栈,使用popd能够回到该文件夹. 3.find -type ...
- C#的Timer(很多相关文章)
再C#里现在有3个Timer类: System.Windows.Forms.Timer System.Threading.Timer System.Timers.Timer 这三个Timer我想大家对 ...
- 线程堆栈大小 pthread_attr_setstacksize 的使用
pthread_create 创建线程时,若不指定分配堆栈大小,系统会分配默认值,查看默认值方法如下: # ulimit -s8192# 上述表示为8M:单位为KB. 也可以通过# ulimit -a ...
- thinkphp5 tp5 获取模块名控制器名方法名
<?php namespace app\index\controller; use think\Db; use think\Controller; class Base extends Cont ...
- solr源码导入eclipse 分类: H4_SOLR/LUCENCE 2014-07-14 14:11 550人阅读 评论(1) 收藏
转载自:http://blog.csdn.net/vltic/article/details/19917377 (1)相应的开发环境准备 (1)jdk1.6+的安装和环境变量配置(命 ...
- Java fork join ForkJoinPool 用法例子
本例是把一个大的数组求和的计算的大任务分解到在小范围内求和的小任务,然后把这些小任务之和加起来就是所求之结果. 技术:JDK8.0, Javafork-join模式下的RecursiveTask技术, ...