构造器最大的作用:创建对象.
为什么使用反射创建对象,为什么不直接来new呢?
在框架中,提供给我们的都是字符串.
-----------------------------------------------------------
使用反射创建对象:
步骤:
1);找到构造器所在类的字节码对象.
2):获取构造器对象.
3):使用反射,创建对象
-----------------------------------------------------------
Constructor<T>类:表示类中构造器的类型,Constructor的实例就是某一个类中的某一个构造器
常用方法:
publicT newInstance(Object... initargs):如调用带参数的构造器,只能使用该方式.
参数:initargs:表示调用构造器的实际参数
返回:返回创建的实例,T表示Class所表示类的类型
如果:一个类中的构造器是外界可以直接访问,同时没有参数.,那么可以直接使用Class类中的newInstance方法创建对象.
public Object newInstance():相当于new 类名();
调用私有的构造器:
注意:java.lang.IllegalArgumentException: wrong number of arguments表示如果你想获取的构造器为private那么通过getConstructor是会报上面的异常,改为getDeclaredConstructor
访问私有的成员:
必须先设置可访问的
对象setAccessible(true)代码:
package com.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Date;
import java.util.Scanner;
public class Main {
//获取指定的一个构造器
public Main(){
System.out.println("我是Main类无参的构造器");
}
public Main(int num){
System.out.println(num);
}
private Main(String statement){
System.out.println("我是带有一个String类型的参数的构造器"+ statement);
}
private Main(String str, int num){
System.out.println("我是带有两个参数的构造器");
}
public static void main(String[] args) throws Exception {
System.out.println("-----------反射调用构造器创建对象----------------");
//1:获取构造器所在类的字节码对象
Class<Main> clz = Main.class;
//2:获取clz对象中所有的构造器
Constructor<Main> con = clz.getDeclaredConstructor(String.class);
//3.使用反射创建对象
//由于main(String..)为私有的因此,设置访问权限
con.setAccessible(true);
String str = "hello";
con.newInstance(str);
}
}
package com.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Date;
import java.util.Scanner;
public class Main {
//获取指定的一个构造器
public Main(){
System.out.println("我是Main类无参的构造器");
}
public Main(int num){
System.out.println(num);
}
private Main(final String statement){
System.out.println("我是带有一个String类型的参数的构造器");
}
private Main(String str, int num){
System.out.println("我是带有两个参数的构造器");
}
private static void getAll(){
//1:获取构造器所在类的字节码对象
Class<Main> clz = Main.class;
//2:获取clz对象中所有的构造器
Constructor<?>[] cs = clz.getConstructors();
System.out.println(cs.length);
for (Constructor<?> c : cs) {
System.out.println(c);
}
cs = clz.getDeclaredConstructors();
System.out.println(cs.length);
for(Constructor<?> c : cs){
System.out.println(c);
}
}
private static void getOne() throws NoSuchMethodException, SecurityException{
//1:获取构造器所在类的字节码对象
Class<Main> clz = Main.class;
//2:获取clz对象中所有的构造器
//需求1:获取public Main()
Constructor<Main> con = clz.getConstructor();
System.out.println(con);
//需求2:获取public Main(String statement)
con = clz.getDeclaredConstructor(String.class);
System.out.println(con);
//需求3:获取private Main(String str, int num)
con = clz.getDeclaredConstructor(String.class, int.class);
System.out.println(con);
}
public static void main(String[] args) throws Exception {
System.out.println("---------类的实例------------------");
//需求1:获取java.util.Date类的字节码对象
//方式1:使用class属性
Class<java.util.Date> clz1 =java.util.Date.class;
//方式2:通过对象的getClass方法获取,getClass是Object类中的方法
java.util.Date date = new java.util.Date();
Class<?> clz2 = date.getClass();
//方式3:通过Class类中的静态方法foeName(String className)
Class<?> clz3 = Class.forName("java.util.Date");
System.out.println(clz1+"\n"+clz2+"\n"+clz3+"\n");
System.out.println("----------获取类的构造器-----------------");
getOne();
System.out.println("-----------获取类的所有的构造器----------------");
getAll();
System.out.println("-----------反射调用构造器创建对象----------------");
//1:获取构造器所在类的字节码对象
Class<Main> clz = Main.class;
//2:获取clz对象中所有的构造器
Constructor<Main> con = clz.getDeclaredConstructor(String.class);
//3.使用反射创建对象
//由于main(String..)为私有的因此,设置访问权限
con.setAccessible(true);
String str = "hello";
con.newInstance(str);
}
}