java懒反_(转)java基础-反射

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、反射方法的其它使用之---通过反射运行配置文件内容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值