【转】Java利用反射机制访问私有化构造器

我们都知道,当一个类的构造方法被设为私有的时候(private),在其他类中是无法用new来实例化一个对象的。

但是有一种方法可以把带有私有构造器的类实例化出对象。

在java的反射机制中,可以通过Class.forName(类名).newInstance()来实例化一个对象,还可以获取类的所有方法和构造方法。

Constructor这个类,表示类构造器,即构造方法。在生成类对象的时候,会调用构造方法。

  1. //例子程序
  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.InvocationTargetException;
  4. import java.lang.reflect.Type;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. public class PrivateClassInstanceTest {
  8. static List<PrivateClassInstance> list = new ArrayList<PrivateClassInstance>();
  9. @SuppressWarnings("unchecked")
  10. public static void main(String[] args) {
  11. Constructor<PrivateClassInstance>[] constructors = null;
  12. try {
  13. // 拿到构造器数组,测试类包含多个私有构造器
  14. constructors = (Constructor<PrivateClassInstance>[]) Class.forName(
  15. "PrivateClassInstance").getDeclaredConstructors();
  16. } catch (ClassNotFoundException e) {
  17. e.printStackTrace();
  18. }
  19. // 按类中定义的顺序输出构造器
  20. for (int i = 0; i < constructors.length; i++) {
  21. Constructor<PrivateClassInstance> con = constructors[i];
  22. System.out.print(con + " ---> ");
  23. // 输出构造器参数的全部类型
  24. Type types[] = con.getGenericParameterTypes();
  25. int typeNums = types.length;
  26. for (int j = 0; j < typeNums; j++) {
  27. System.out.print(types[j]);
  28. }
  29. System.out.print(" ===> ");
  30. con.setAccessible(true); // 得到私有访问权限,如果不设置,则无法实例化对象
  31. //实例化对象
  32. PrivateClassInstance p;
  33. try {
  34. if (typeNums == 1) {
  35. p = con.newInstance(1);
  36. } else if (typeNums == 2) {
  37. p = con.newInstance("Li","nK");
  38. } else {
  39. p = con.newInstance();
  40. }
  41. list.add(p);
  42. } catch (IllegalArgumentException e) {
  43. e.printStackTrace();
  44. } catch (InstantiationException e) {
  45. e.printStackTrace();
  46. } catch (IllegalAccessException e) {
  47. e.printStackTrace();
  48. } catch (InvocationTargetException e) {
  49. e.printStackTrace();
  50. }
  51. }
  52. for(PrivateClassInstance p : list) {
  53. System.out.println(p);
  54. }
  55. }
  56. }
  57. class PrivateClassInstance {
  58. private PrivateClassInstance(String a, String b) {
  59. System.out.println("has two param");
  60. }
  61. private PrivateClassInstance() {
  62. System.out.println("no param");
  63. }
  64. private PrivateClassInstance(int n) {
  65. System.out.println("has one param");
  66. }
  67. }

输出结果:

private PrivateClassInstance(java.lang.String,java.lang.String) ---> class java.lang.Stringclass java.lang.String ===> has two param

private PrivateClassInstance() --->  ===> no param

private PrivateClassInstance(int) ---> int ===> has one param

PrivateClassInstance@c17164

PrivateClassInstance@1fb8ee3

PrivateClassInstance@61de33

最后打印出保存在list里的三个对象。

原文出处:http://wojiaorara.iteye.com/blog/1418359

上一篇:BurpSuite+SQLmap的一种另类扫描


下一篇:阅读Configuration源码