[AppleScript] 纯文本查看 复制代码
利用反射运行一个私有的方法 | 对比 public 修饰的方法[/align]
// 获取字节码对象 |
Class clazz = Class.forName("com.heima.Student"); | Class clazz = Class.forName("com.itheima_01.Student");
// 创建学生对象 |
Object stu = clazz.newInstance(); | Object stu = clazz.newInstance();
// 暴力反射获取方法 |
Method method = clazz.getDeclaredMethod("method"); | Method m = clazz.getMethod("method");
// 让jvm不检查权限 |
method.setAccessible(true); |
// 执行方法 |
method.invoke(stu); | m.invoke(stu);
(二)面试加分项
让字符串可变
String s = "abc";
Class clazz = s.getClass();
Field field = clazz.getDeclaredField("value");
field.setAccessible(true);
char[] chs = (char[]) field.get(s);
chs[0] = 'Q';
System.out.println(s);
//----------------------------------------------------
String s = "abc";
Class clazz = s.getClass();//因为已经有对象存在了,所以用getClass就可以获取到了
Field field = clazz.getDeclaredField("value");//可以看到,但是得不到这个对象
field.setAccessible(true);
//Object object = field.get(s);
//System.out.println(object);// [C@1950198
char [] chs = (char[]) field.get(s);//此时就已经得到了字符串中存储字符的那个数组的对象了.
//System.out.println(Arrays.toString(chs));
chs[0] = 'Q';
System.out.println(s);
字符串在正常情况下是不可以改变的.
但是在底层字符串是用 private final 修饰的一个 char 类型的数组.这个数组的名字是 value[];
没有对外提供对应的getXXX和setXXX的方法,所以说,外界无法获取到value这个数组的对象,无法变更
又因为是用final修饰的,value这个变量记录的地址值是无法改变的.
但是换句话来讲,如果我们能得到数组的对象.虽然他是用final修饰的,不能改变地址值
但是可以修改内部的属性值.(可以改变内部的元素)
所以用反射的知识点,获取到value对象,然后对数组的索引上的值就可以修改了.
(三)通过无参构造创建对象
1 通过无参构造创建Person类的对象
//通过Class类中的newInstance()方法直接创建无参的对象.是一种简化的写法.
Class clazz = Class.forName("com.heima.bean.Person"); //先要获取字节码文件的对象
Person p = (Person) clazz.newInstance(); //通过无参构造创建对象
以上的两行代码等同于
Person p = new Person();
用Constructor通过无参构造创建对象
Class clazz = Class.forName("com.itheima_01_bean.Bean");
Constructor cons = clazz.getConstructor();//可变参数可以什么都不传,此时就跟无参构造匹配
Object obj = cons.newInstance();
通过私有的无参构造创建对象 //非public
Class clazz = Class.forName("com.heima.demo.Student");
Constructor c = clazz.getDeclaredConstructor();
c.setAccessible(true);
Student s = (Student) c.newInstance();
System.out.println(s);
(四)通过有参构造创建对象
2 通过有参构造创建Person类的对象
Class clazz = Class.forName("com.heima.bean.Person"); //先要获取字节码文件的对象
Constructor c = clazz.getConstructor(String.class,int.class);//通过这个字节码文件的对象,来获取有参构造
Person p = (Person) c.newInstance("张三",23); //通过有参构造创建对象
以上三行代码等同于
Person p = new Person("张三",23);
//上面的是通过反射,class文件创建的对象
//下面的是通过java文件,常规方式创建的对象.
通过私有的有参构造创建对象 //非public
Class clazz = Class.forName("com.heima.demo.Student");
Constructor c = clazz.getDeclaredConstructor(String.class,int.class);
c.setAccessible(true);
Student s = (Student) c.newInstance("张三",20);
System.out.println(s);