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

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

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

 

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

 

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

 

 

//例子程序

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

public class PrivateClassInstanceTest {

	static List list = new ArrayList();

	@SuppressWarnings("unchecked")
	public static void main(String[] args) {

		Constructor[] constructors = null;
		try {
			// 拿到构造器数组,测试类包含多个私有构造器
			constructors = (Constructor[]) Class.forName(
					"PrivateClassInstance").getDeclaredConstructors();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		// 按类中定义的顺序输出构造器
		for (int i = 0; i < constructors.length; i++) {
			Constructor con = constructors[i];

			System.out.print(con + " ---> ");

			// 输出构造器参数的全部类型
			Type types[] = con.getGenericParameterTypes();

			int typeNums = types.length;

			for (int j = 0; j < typeNums; j++) {
				System.out.print(types[j]);
			}
			System.out.print(" ===> ");
			

			con.setAccessible(true); // 得到私有访问权限,如果不设置,则无法实例化对象

			//实例化对象
			PrivateClassInstance p;
			try {
				if (typeNums == 1) {
					p = con.newInstance(1);
				} else if (typeNums == 2) {
					p = con.newInstance("Li","nK");
				} else {
					p = con.newInstance();
				}
				list.add(p);
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}

		}
		
		for(PrivateClassInstance p : list) {
			System.out.println(p);
		}

	}
}

class PrivateClassInstance {

	private PrivateClassInstance(String a, String b) {
		System.out.println("has two param");
	}

	private PrivateClassInstance() {
		System.out.println("no param");
	}

	private PrivateClassInstance(int n) {
		System.out.println("has one param");
	}

}
 

 

 

输出结果:

 

 

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里的三个对象。

 

你可能感兴趣的:(java)