2、通过反射获取构造方法并使用:
student类:
packagefanshe;public classStudent {//---------------构造方法-------------------//(默认的构造方法)
Student(String str){
System.out.println("(默认)的构造方法 s = " +str);
}//无参构造方法
publicStudent(){
System.out.println("调用了公有、无参构造方法执行了。。。");
}//有一个参数的构造方法
public Student(charname){
System.out.println("姓名:" +name);
}//有多个参数的构造方法
public Student(String name ,intage){
System.out.println("姓名:"+name+"年龄:"+ age);//这的执行效率有问题,以后解决。
}//受保护的构造方法
protected Student(booleann){
System.out.println("受保护的构造方法 n = " +n);
}//私有构造方法
private Student(intage){
System.out.println("私有的构造方法 年龄:"+age);
}
}
共有6个构造方法;
测试类:
packagefanshe;importjava.lang.reflect.Constructor;/** 通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员;
*
* 1.获取构造方法:
* 1).批量的方法:
* public Constructor[] getConstructors():所有"公有的"构造方法
public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
* 2).获取单个的方法,并调用:
* public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
* public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
*
* 调用构造方法:
* Constructor-->newInstance(Object... initargs)*/
public classConstructors {public static void main(String[] args) throwsException {//1.加载Class对象
Class clazz = Class.forName("fanshe.Student");//2.获取所有公有构造方法
System.out.println("**********************所有公有构造方法*********************************");
Constructor[] conArray=clazz.getConstructors();for(Constructor c : conArray){
System.out.println(c);
}
System.out.println("************所有的构造方法(包括:私有、受保护、默认、公有)***************");
conArray=clazz.getDeclaredConstructors();for(Constructor c : conArray){
System.out.println(c);
}
System.out.println("*****************获取公有、无参的构造方法*******************************");
Constructor con= clazz.getConstructor(null);//1>、因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型,切记是类型//2>、返回的是描述这个无参构造函数的类对象。
System.out.println("con = " +con);//调用构造方法
Object obj =con.newInstance();//System.out.println("obj = " + obj);//Student stu = (Student)obj;
System.out.println("******************获取私有构造方法,并调用*******************************");
con= clazz.getDeclaredConstructor(char.class);
System.out.println(con);//调用构造方法
con.setAccessible(true);//暴力访问(忽略掉访问修饰符)
obj = con.newInstance('男');
}
}
后台输出:
**********************所有公有构造方法*********************************
public fanshe.Student(java.lang.String,int)public fanshe.Student(char)publicfanshe.Student()************所有的构造方法(包括:私有、受保护、默认、公有)***************
private fanshe.Student(int)protected fanshe.Student(boolean)public fanshe.Student(java.lang.String,int)public fanshe.Student(char)publicfanshe.Student()
fanshe.Student(java.lang.String)*****************获取公有、无参的构造方法*******************************con= publicfanshe.Student()
调用了公有、无参构造方法执行了。。。******************获取私有构造方法,并调用*******************************
public fanshe.Student(char)
姓名:男
调用方法:
1.获取构造方法:
1).批量的方法:
public Constructor[] getConstructors():所有"公有的"构造方法
public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
2).获取单个的方法,并调用:
public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
调用构造方法:
Constructor-->newInstance(Object... initargs)
2、newInstance是 Constructor类的方法(管理构造函数的类)
api的解释为:
newInstance(Object... initargs)
使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。
它的返回值是T类型,所以newInstance是创建了一个构造方法的声明类的新实例对象。并为之调用
3、获取成员变量并调用
student类:
packagefanshe.field;public classStudent {publicStudent(){
}//**********字段*************//
publicString name;protected intage;charsex;privateString phoneNum;
@OverridepublicString toString() {return "Student [name=" + name + ", age=" + age + ", sex=" +sex+ ", phoneNum=" + phoneNum + "]";
}
}
测试类:
packagefanshe.field;importjava.lang.reflect.Field;/** 获取成员变量并调用:
*
* 1.批量的
* 1).Field[] getFields():获取所有的"公有字段"
* 2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
* 2.获取单个的:
* 1).public Field getField(String fieldName):获取某个"公有的"字段;
* 2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
*
* 设置字段的值:
* Field --> public void set(Object obj,Object value):
* 参数说明:
* 1.obj:要设置的字段所在的对象;
* 2.value:要为字段设置的值;
**/
public classFields {public static void main(String[] args) throwsException {//1.获取Class对象
Class stuClass = Class.forName("fanshe.field.Student");//2.获取字段
System.out.println("************获取所有公有的字段********************");
Field[] fieldArray=stuClass.getFields();for(Field f : fieldArray){
System.out.println(f);
}
System.out.println("************获取所有的字段(包括私有、受保护、默认的)********************");
fieldArray=stuClass.getDeclaredFields();for(Field f : fieldArray){
System.out.println(f);
}
System.out.println("*************获取公有字段**并调用***********************************");
Field f= stuClass.getField("name");
System.out.println(f);//获取一个对象
Object obj = stuClass.getConstructor().newInstance();//产生Student对象--》Student stu = new Student();//为字段设置值
f.set(obj, "刘德华");//为Student对象中的name属性赋值--》stu.name = "刘德华"//验证
Student stu =(Student)obj;
System.out.println("验证姓名:" +stu.name);
System.out.println("**************获取私有字段****并调用********************************");
f= stuClass.getDeclaredField("phoneNum");
System.out.println(f);
f.setAccessible(true);//暴力反射,解除私有限定
f.set(obj, "18888889999");
System.out.println("验证电话:" +stu);
}
}
后台输出:
************获取所有公有的字段********************
publicjava.lang.String fanshe.field.Student.name************获取所有的字段(包括私有、受保护、默认的)********************
publicjava.lang.String fanshe.field.Student.nameprotected intfanshe.field.Student.agecharfanshe.field.Student.sexprivatejava.lang.String fanshe.field.Student.phoneNum*************获取公有字段**并调用***********************************
publicjava.lang.String fanshe.field.Student.name
验证姓名:刘德华**************获取私有字段****并调用********************************
privatejava.lang.String fanshe.field.Student.phoneNum
验证电话:Student [name=刘德华, age=0, sex=
由此可见
调用字段时:需要传递两个参数:
Object obj = stuClass.getConstructor().newInstance();//产生Student对象--》Student stu = new Student();
//为字段设置值
f.set(obj, "刘德华");//为Student对象中的name属性赋值--》stu.name = "刘德华"
第一个参数:要传入设置的对象,第二个参数:要传入实参
4、获取成员方法并调用
student类:
packagefanshe.method;public classStudent {//**************成员方法***************//
public voidshow1(String s){
System.out.println("调用了:公有的,String参数的show1(): s = " +s);
}protected voidshow2(){
System.out.println("调用了:受保护的,无参的show2()");
}voidshow3(){
System.out.println("调用了:默认的,无参的show3()");
}private String show4(intage){
System.out.println("调用了,私有的,并且有返回值的,int参数的show4(): age = " +age);return "abcd";
}
}
测试类:
packagefanshe.method;importjava.lang.reflect.Method;/** 获取成员方法并调用:
*
* 1.批量的:
* public Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类)
* public Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的)
* 2.获取单个的:
* public Method getMethod(String name,Class>... parameterTypes):
* 参数:
* name : 方法名;
* Class ... : 形参的Class类型对象
* public Method getDeclaredMethod(String name,Class>... parameterTypes)
*
* 调用方法:
* Method --> public Object invoke(Object obj,Object... args):
* 参数说明:
* obj : 要调用方法的对象;
* args:调用方式时所传递的实参;
):*/
public classMethodClass {public static void main(String[] args) throwsException {//1.获取Class对象
Class stuClass = Class.forName("fanshe.method.Student");//2.获取所有公有方法
System.out.println("***************获取所有的”公有“方法*******************");
stuClass.getMethods();
Method[] methodArray=stuClass.getMethods();for(Method m : methodArray){
System.out.println(m);
}
System.out.println("***************获取所有的方法,包括私有的*******************");
methodArray=stuClass.getDeclaredMethods();for(Method m : methodArray){
System.out.println(m);
}
System.out.println("***************获取公有的show1()方法*******************");
Method m= stuClass.getMethod("show1", String.class);
System.out.println(m);//实例化一个Student对象
Object obj =stuClass.getConstructor().newInstance();
m.invoke(obj,"刘德华");
System.out.println("***************获取私有的show4()方法******************");
m= stuClass.getDeclaredMethod("show4", int.class);
System.out.println(m);
m.setAccessible(true);//解除私有限定
Object result = m.invoke(obj, 20);//需要两个参数,一个是要调用的对象(获取有反射),一个是实参
System.out.println("返回值:" +result);
}
}
控制台输出:
***************获取所有的”公有“方法*******************
public voidfanshe.method.Student.show1(java.lang.String)public final void java.lang.Object.wait(long,int) throwsjava.lang.InterruptedExceptionpublic final native void java.lang.Object.wait(long) throwsjava.lang.InterruptedExceptionpublic final void java.lang.Object.wait() throwsjava.lang.InterruptedExceptionpublic booleanjava.lang.Object.equals(java.lang.Object)publicjava.lang.String java.lang.Object.toString()public native intjava.lang.Object.hashCode()public final nativejava.lang.Class java.lang.Object.getClass()public final native voidjava.lang.Object.notify()public final native voidjava.lang.Object.notifyAll()***************获取所有的方法,包括私有的*******************
public voidfanshe.method.Student.show1(java.lang.String)private java.lang.String fanshe.method.Student.show4(int)protected voidfanshe.method.Student.show2()voidfanshe.method.Student.show3()***************获取公有的show1()方法*******************
public voidfanshe.method.Student.show1(java.lang.String)
调用了:公有的,String参数的show1(): s=刘德华***************获取私有的show4()方法******************
private java.lang.String fanshe.method.Student.show4(int)
调用了,私有的,并且有返回值的,int参数的show4(): age= 20返回值:abcd
由此可见:
m = stuClass.getDeclaredMethod("show4", int.class);//调用制定方法(所有包括私有的),需要传入两个参数,第一个是调用的方法名称,第二个是方法的形参类型,切记是类型。
System.out.println(m);
m.setAccessible(true);//解除私有限定
Object result = m.invoke(obj, 20);//需要两个参数,一个是要调用的对象(获取有反射),一个是实参
System.out.println("返回值:" + result);
其实这里的成员方法:在模型中有属性一词,就是那些setter()方法和getter()方法。还有字段组成,这些内容在内省中详解
5、反射main方法
student类:
packagefanshe.main;public classStudent {public static voidmain(String[] args) {
System.out.println("main方法执行了。。。");
}
}
测试类:
packagefanshe.main;importjava.lang.reflect.Method;/*** 获取Student类的main方法、不要与当前的main方法搞混了*/
public classMain {public static voidmain(String[] args) {try{//1、获取Student对象的字节码
Class clazz = Class.forName("fanshe.main.Student");//2、获取main方法
Method methodMain = clazz.getMethod("main", String[].class);//第一个参数:方法名称,第二个参数:方法形参的类型,//3、调用main方法//methodMain.invoke(null, new String[]{"a","b","c"});//第一个参数,对象类型,因为方法是static静态的,所以为null可以,第二个参数是String数组,这里要注意在jdk1.4时是数组,jdk1.5之后是可变参数//这里拆的时候将 new String[]{"a","b","c"} 拆成3个对象。。。所以需要将它强转。
methodMain.invoke(null, (Object)new String[]{"a","b","c"});//方式一//methodMain.invoke(null, new Object[]{new String[]{"a","b","c"}});//方式二
}catch(Exception e) {
e.printStackTrace();
}
}
}
控制台输出:
main方法执行了。。。
6、反射方法的其它使用之---通过反射运行配置文件内容