Java反射,获取类的公有、私有的构造函数(有参,无参)、方法(有参,无参)、属性
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Java反射,获取类的公有、私有的构造函数(有参,⽆参)、
⽅法(有参,⽆参)、属性
Class类与ng.reflect类库⼀起对反射进⾏了⽀持,该类库包含Field、Method和Constructor类,这些类的对象由JVM在启动时创建,⽤以表⽰未知类⾥对应的成员。
这样的话就可以使⽤Contructor创建新的对象,⽤get()和set()⽅法获取和修改类中与Field对象关联的字段,⽤invoke()⽅法调⽤与Method对象关联的⽅法。
另外,还可以调⽤getFields()、getMethods()和getConstructors()等许多便利的⽅法,以返回表⽰字段、⽅法、以及构造器对象的数组,这样,对象信息可以在运⾏时被完全确定下来,⽽在编译时不需要知道关于类的任何事情。
⾸先创建⼀个类
1public class Per {
2public String name="sunshine";
3private int age=28;
4public double weight=65.50;
5
6public Per(){
7 System.out.println("测试反射获取公有⽆参构造函数");
8 }
9private Per(String name){
=name;
11 System.out.println("测试反射获取私有有参构造函数");
12 }
13public Per(String name,int age){
=name;
15this.age=age;
16 System.out.println("测试反射获取公有有多个参数构造函数name:"+name+" age:"+age);17 }
18public String methodT1(){
19 System.out.println("测试反射获取公有⽆参⽅法");
20return null;
21 }
22public String methodT1(String name,int age){
23 System.out.println("测试反射获取公有多个参⽅法");
24 System.out.println(name+":"+age);
25return null;
26 }
27private String methodT1(String name){
28 System.out.println("测试反射获取私有有参⽅法");
29 System.out.println("name:"+name);
30return null;
31 }
32public String methodT2(int[] arr,String[] str){
33 System.out.println("测试反射获取公有有数组参⽅法");
34 System.out.println("int[] arr:"+arr+"String[] str:"+str);
35return null;
36 }
37public static void main(String[] args) {
38 System.out.println("测试反射获取main⽅法");
39 }
40 }
1.使⽤java反射获取类的构造函数(公有、私有)(有参,⽆参)
1import ng.reflect.Constructor;
2import ng.reflect.Field;
3import ng.reflect.Method;
4
5import org.junit.AfterClass;
6import org.junit.BeforeClass;
7import org.junit.Test;
8/**
9 * 测试使⽤java反射获取类的构造函数并创建对象
10 * @author Sunshine
11 *
12*/
13public class ReflectPer {
14private static Class class1;
15//因为java反射获取类时都需要加载类,在这⾥我就使⽤Junit的@beforeclass来去加载类,不⽤在每个测试⽅法中重复创建
16//注:@beforeclass在执⾏测试⽅法前运⾏
17 @BeforeClass
18public static void beforeClass() throws Exception{
19 System.out.println("====测试⽅法启动前先加载类====");
20 class1 = Class.forName("myPractise.Per");//加载类
21 }
22//获取类的公有⽆参构造函数,并创建对象
23 @Test
24public void test1() throws Exception{
25 Constructor constructor = class1.getConstructor(null);//获取公有⽆参构造器,值为null代表获取⽆参构造器
26 Per per = (Per) constructor.newInstance(null);//创建对象,返回的是Object类型要强转
27 System.out.println();//可以调⽤类的属性-----成功
28 }
29//获取类的公有参构造函数,并创建对象
30 @Test
31public void test2()throws Exception{
32 Constructor constructor = class1.getConstructor(String.class,int.class);//获取公有多个参数构造器,参数为构造器中参数的类型
33 Per per = (Per)constructor.newInstance("baby",24);//创建对象
34 }
35//获取类的私有有参构造函数,并创建对象
36 @Test
37public void test3()throws Exception{
38 Constructor constructor = class1.getDeclaredConstructor(String.class);//获取公有多个参数构造器,参数为构造器中参数的类型
39 constructor.setAccessible(true);//暴⼒反射,只有将属性设置为true才可以创建对象
40 Per per = (Per)constructor.newInstance("baby");
41 System.out.println(per.weight);//可以调⽤类的属性-----成功
42//注:通常情况下⼀个类不可以访问另⼀个类的私有的属性,⽅法。
但是通过java反射可以
43 }
44 @AfterClass
45public static void afterClass(){
46 System.out.println("===测试完成将对象赋值为null===");
47 }
48 }
2.使⽤java反射获取类的⽅法(公有、私有)(有参,⽆参)
1import ng.reflect.Constructor;
2import ng.reflect.Field;
3import ng.reflect.Method;
4
5import org.junit.AfterClass;
6import org.junit.BeforeClass;
7import org.junit.Test;
8/**
9 * 测试使⽤java反射获取类⽅法
10 * @author Sunshine
11 *
12*/
13public class ReflectPer {
14private static Class class1;
15private static Per per;
16//因为java反射获取类时都需要加载类,在这⾥我就使⽤Junit的@beforeclass来去加载类,不⽤在每个⽅法中重复创建
17//注:@beforeclass在执⾏测试⽅法前运⾏
18 @BeforeClass
19public static void beforeClass() throws Exception{
20 System.out.println("====测试⽅法启动前先加载类====");
21 class1 = Class.forName("myPractise.Per");//加载类
22 per = (Per) class1.getConstructor(null).newInstance(null);//使⽤反射创建对象
23 }
24
25//获取类的公有⽆参⽅法
26 @Test
27public void test4()throws Exception{
28 Method method = class1.getMethod("methodT1", null);//获取指定的⽅法,参数为⽅法名和该⽅法的参数类型,因为我们这是测试⽆参的⽅法,所以传⼊null
29 method.invoke(per, null);//使⽤invoke⽅法来调⽤,参数为指定对象,该⽅法传⼊的参数,因为我们这是测试⽆参的⽅法,所以传⼊null
30 }
31//获取类的公有有参⽅法
32 @Test
33public void test5()throws Exception{
34 Method method = class1.getMethod("methodT1", String.class,int.class);//获取指定的⽅法,参数为⽅法名和该⽅法的参数类型
35 method.invoke(per, "sunshine",25);//使⽤invoke⽅法来调⽤,参数为指定对象,该⽅法传⼊的参数
36 }
37 @Test
38public void test6()throws Exception{
39 Method method = class1.getDeclaredMethod("methodT1", String.class);//获取指定的⽅法,参数为⽅法名和该⽅法的参数类型
40 method.setAccessible(true);//暴⼒反射,默认为false,未设置则调⽤类的私有⽅法不成功
41 method.invoke(per, "sunshine");//使⽤invoke⽅法来调⽤,参数为指定对象,该⽅法传⼊的参数
42 System.out.println(method.getReturnType());//获取到该类指定⽅法的返回值类型
43 }
44 @Test
45public void test7()throws Exception{
46 Method method = class1.getMethod("methodT2", int[].class,String[].class);
47 method.invoke(per, new int[]{1,2},new String[]{"AA","BB"});
48 }
49//获取某个类的main⽅法⽐较特殊也可以说是只要传⼊的参数为单个数组特殊
50//jdk5之后新增特性--可变参数
51//在加载时会将传⼊的数组进⾏拆分,这样就会报错,ng.IllegalArgumentException: wrong number of arguments 错误的参数个数
52//这时候我们可以欺骗⼀下虚拟机,告诉他我们传⼊的是⼀个对象将new String[]{"AA","BB"}换成(Object)new String[]{"AA","BB"}
53 @Test
54public void test8()throws Exception{
55 Method method = class1.getMethod("main",String[].class);
56 method.invoke(per,(Object)new String[]{"AA","BB"});
57 }
58 @AfterClass
59public static void afterClass(){
60 System.out.println("===测试完成将对象赋值为null===");
61 }
62 }
3.使⽤java反射获取类的属性(公有、私有)
1import ng.reflect.Constructor;
2import ng.reflect.Field;
3import ng.reflect.Method;
4import java.util.Iterator;
5
6import org.junit.AfterClass;
7import org.junit.BeforeClass;
8import org.junit.Test;
9
10/**
11 * 测试使⽤java反射获取类的属性
12 *
13 * @author Sunshine
14 *
15*/
16public class ReflectPer {
17private static Class class1;
18private static Per per;
19
20// 因为java反射获取类时都需要加载类,在这⾥我就使⽤Junit的@beforeclass来去加载类,不⽤在每个测试⽅法中重复创建21// 注:@beforeclass在执⾏测试⽅法前运⾏
22 @BeforeClass
23public static void beforeClass() throws Exception {
24 System.out.println("====测试⽅法启动前先加载类====");
25 class1 = Class.forName("myPractise.Per");// 加载类
26 per = (Per) class1.getConstructor(null).newInstance(null);// 使⽤反射创建对象
27 }
28// 公有属性
29 @Test
30public void test9() throws Exception {
31// 获取某个属性,参数是属性名
32 Field field = class1.getField("name");
33// 输出属性值,需要传⼊指定对象
34 System.out.println(field.get(per));
35// 获取属性的类型
36 System.out.println(field.getType());
37// 获取多个属性
38 Field[] field1 = class1.getFields();
39// 增强for循环Jdk1.5后的新特性,只适⽤于数组和实现了Iterator的集合
40for (Field str : field1) {
41 System.out.println(str);
42 }
43// 设置属性值
44 field.set(per, "baby");
45 System.out.println(field.get(per));
46 }
47//私有属性
48 @Test
49public void test10() throws Exception {
50 Field field = class1.getDeclaredField("age");
51 field.setAccessible(true);//暴⼒反射
52 System.out.println(field.get(per));
53 }
54
55 @AfterClass
56public static void afterClass() {
57 System.out.println("===测试完成将对象赋值为null===");
58 }
59 }。