Java反射——访问构造方法

反射

通过Java的反射机制,可以在程序中访问已经装载到JVM中的Java对象的描述,实现访问,检测和修改描述Java对象本身信息的功能。通过反射可以访问构造方法,成员变量,和成员方法。

访问成员变量:Java反射——访问成员变量
访问成员方法:Java反射——访问成员方法

访问构造方法

利用Constructor对象可以操纵相应的构造方法。
在这里插入图片描述
Constructor类中提供的常用方法:

方法 说明
isVarArgs() 查看该构造方法是否允许带有可变数量的参数,如果允许则返回true,反之返回false
getParameterTypes() 按照声明顺序以Class数组的形式获得该构造方法的各个参数类型
gerExceptionTypes() 以Class数组的形式获得该构造方法可能抛出的异常
newInstance(Object…initargs) 通过该构造方法利用指定参数创建一个该类的对象,如果未设置参数则表示采取默认无参的构造方法
setAccessible(boolean fasg) 如果该构造方法的修饰符为private,默认不允许通过反射创建对象,需要通过执行该方法,并将入口参数设置为true,则允许
getModifiers() 获得可以解析出该构造方法所采用修饰符的整数

getModifiers()方法的返回值是所表示的修饰符信息,在该类中提供了一系列用来解析的静态方法,既可以查看是否被指定的修饰符修饰,还可以以字符串的形式获得所有修饰符。
Modifier类中的常用解析方法:

静态方法 说明
isPublic(int mod) 查看是否被public修饰符修饰,如果是返回true,反之返回false
isProtected(int mod) 查看是否被protected修饰符修饰,如果是返回true,反之返回false
isPrivate(int mod) 查看是否被private修饰符修饰,如果是返回true,反之返回false
isStatic(int mod) 查看是否被static修饰符修饰,如果是返回true,反之返回false
isFinal(int mod) 查看是否被Final修饰符修饰,如果是返回true,反之返回false
toString(int mod) 以字符串形式返回所有修饰符

首先创建变量,并且创建些许构造方法和一个toString方法。

public class Study {
    
    
	int id;
	String name;
	double price;

	// 创建无参构造方法
	public Study() {
    
    
		super();
	}

	// 创建有一个参数的构造方法
	public Study(int id) {
    
    
		super();
		this.id = id;
	}

	// 创建私有的并且有三个参数的构造方法
	private Study(int id, String name, double price) {
    
    
		super();
		this.id = id;
		this.name = name;
		this.price = price;
	}

	public String toString() {
    
    
		return "Study [id=" + id + ", name=" + name + ", price=" + price + "]";
	}

}

再创建一个Study2类来反射上面创建好的Study类

public class Study2 {
    
    

	public static void main(String[] args) {
    
    
		try {
    
    
			Class c = Class.forName("study.czm.Study");//创建class对象
			//获取构造方法
			Constructor cos[] = c.getConstructors();
			for(Constructor cs:cos) {
    
    
				System.out.println(Modifier.toString(cs.getModifiers()));
			}
		} catch (ClassNotFoundException e) {
    
    
			e.printStackTrace();
		}
	}
}

运行结果:
在这里插入图片描述
成功获取了Study类构造方法的修饰符,因为调用的是getConstructors()方法,所有只可以获取public修饰的方法,改成getDeclaredConstructors()方法就可以获取全部方法的修饰符了
在这里插入图片描述

public class Study2 {
    
    

	public static void main(String[] args) {
    
    
		try {
    
    
			Class c = Class.forName("study.czm.Study");//创建class对象
			//获取构造方法
			Constructor cos[] = c.getDeclaredConstructors();
			for(Constructor cs:cos) {
    
    
				System.out.print(Modifier.toString(cs.getModifiers()) + " ");//获取修饰符
				System.out.print(cs.getName() + "(");//获取方法名
				Class p[] = cs.getParameterTypes();//获取参数
				for(int i=0; i<p.length; i++) {
    
    
					System.out.print(p[i].getSimpleName()+" arge ");
				}
				System.out.println(") {  }");
			}
			
		} catch (ClassNotFoundException e) {
    
    
			e.printStackTrace();
		}
	}
}

现在呢已经将所有的构造方法,包括方法名,参数都获取出来了。
在这里插入图片描述
在循环外创建一个无参构造方法对象

//创建对象
			Constructor cst1 = c.getDeclaredConstructor();//无参构造方法
			Object obj = cst1.newInstance();//创建Object对象,这个Object对象实质上就是Study类反射出来的对象
			System.out.println(obj.toString());

这实质上就是反射的Study类中那个无参的个构造方法
在这里插入图片描述
里面的变量全为默认值。
再创建一个有参的构造方法,并且给id赋值

Constructor cst2 = c.getDeclaredConstructor(int.class);//有参构造方法
			obj = cst2.newInstance(123);//创建Object对象,这个Object对象实质上就是Study类反射出来的对象
			System.out.println(obj.toString());

在这里插入图片描述
id的值变成了123
再来创建最后一个构造方法,有三个参数的构造方法,并且修饰符是private。再给三个参数赋值

Constructor cst3 = c.getDeclaredConstructor(int.class,String.class,double.class);//有参构造方法
			obj = cst2.newInstance(-1,"反射",3.14);//创建Object对象,这个Object对象实质上就是Study类反射出来的对象
			System.out.println(obj.toString());

如果直接这样运行就会报错,因为它的修饰符是private,需要获取到权限才可以进行操作,添加一行代码:setAccessible(true)并且将参数设置为true。

Constructor cst3 = c.getDeclaredConstructor(int.class,String.class,double.class);//有参构造方法
			cst3.setAccessible(true);//获取操作权限
			obj = cst3.newInstance(-1,"反射",3.14);//创建Object对象,这个Object对象实质上就是Study类反射出来的对象
			System.out.println(obj.toString());

这样就没有问题了
在这里插入图片描述
完整代码:

public class Study2 {
    
    

	public static void main(String[] args) {
    
    
		try {
    
    
			Class c = Class.forName("study.czm.Study");// 创建class对象
			// 获取构造方法
			Constructor cos[] = c.getDeclaredConstructors();
			for (Constructor cs : cos) {
    
    
				System.out.print(Modifier.toString(cs.getModifiers()) + " ");// 获取修饰符
				System.out.print(cs.getName() + "(");// 获取方法名
				Class p[] = cs.getParameterTypes();// 获取参数
				for (int i = 0; i < p.length; i++) {
    
    
					System.out.print(p[i].getSimpleName() + " arge ");
				}
				System.out.println(") {  }");
			}

			// 创建对象
			Constructor cst1 = c.getDeclaredConstructor();// 无参构造方法
			Object obj = cst1.newInstance();// 创建Object对象,这个Object对象实质上就是Study类反射出来的对象
			System.out.println(obj.toString());

			Constructor cst2 = c.getDeclaredConstructor(int.class);// 有参构造方法
			obj = cst2.newInstance(123);// 创建Object对象,这个Object对象实质上就是Study类反射出来的对象
			System.out.println(obj.toString());

			Constructor cst3 = c.getDeclaredConstructor(int.class, String.class, double.class);// 有参构造方法
			cst3.setAccessible(true);// 获取操作权限
			obj = cst3.newInstance(-1, "反射", 3.14);// 创建Object对象,这个Object对象实质上就是Study类反射出来的对象
			System.out.println(obj.toString());

		} catch (ClassNotFoundException e) {
    
    
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
    
    
			e.printStackTrace();
		} catch (SecurityException e) {
    
    
			e.printStackTrace();
		} catch (InstantiationException e) {
    
    
			e.printStackTrace();
		} catch (IllegalAccessException e) {
    
    
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
    
    
			e.printStackTrace();
		} catch (InvocationTargetException e) {
    
    
			e.printStackTrace();
		}
	}
}

运行效果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/javanofa/article/details/104732594