Java反射,获取类的公有、私有的构造函数(有参,⽆参)、
⽅法(有参,⽆参)、属性
Class类与flect类库⼀起对反射进⾏了⽀持,该类库包含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){
10this.name=name;
11 System.out.println("测试反射获取私有有参构造函数");
12 }
13public Per(String name,int age){
14this.name=name;
15this.age=age;
java接口有没有构造方法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 flect.Constructor;
2import flect.Field;
3import flect.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 = Constructor(null);//获取公有⽆参构造器,值为null代表获取⽆参构造器
26 Per per = (Per) wInstance(null);//创建对象,返回的是Object类型要强转
27 System.out.println(per.name);//可以调⽤类的属性-----成功
28 }
29//获取类的公有参构造函数,并创建对象
30 @Test
31public void test2()throws Exception{
32 Constructor constructor = Constructor(String.class,int.class);//获取公有多个参数构造器,参数为构造器中参数的类型
33 Per per = (wInstance("baby",24);//创建对象
34 }
35//获取类的私有有参构造函数,并创建对象
36 @Test
37public void test3()throws Exception{
38 Constructor constructor = DeclaredConstructor(String.class);//获取公有多个参数构造器,参数为构造器中参数的类型
39 constructor.setAccessible(true);//暴⼒反射,只有将属性设置为true才可以创建对象
40 Per per = (wInstance("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 flect.Constructor;
2import flect.Field;
3import flect.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) Constructor(null).newInstance(null);//使⽤反射创建对象
23 }
24
25//获取类的公有⽆参⽅法
26 @Test
27public void test4()throws Exception{
28 Method method = Method("methodT1", null);//获取指定的⽅法,参数为⽅法名和该⽅法的参数类型,因为我们这是测试⽆参的⽅法,所以传⼊null
29 method.invoke(per, null);//使⽤invoke⽅法来调⽤,参数为指定对象,该⽅法传⼊的参数,因为我们这是测试⽆参的⽅法,所以传⼊null
30 }
31//获取类的公有有参⽅法
32 @Test
33public void test5()throws Exception{
34 Method method = Method("methodT1", String.class,int.class);//获取指定的⽅法,参
数为⽅法名和该⽅法的参数类型
35 method.invoke(per, "sunshine",25);//使⽤invoke⽅法来调⽤,参数为指定对象,该⽅法传⼊的参数
36 }
37 @Test
38public void test6()throws Exception{
39 Method method = DeclaredMethod("methodT1", String.class);//获取指定的⽅法,参数为⽅法名和该⽅法的参数类型
40 method.setAccessible(true);//暴⼒反射,默认为false,未设置则调⽤类的私有⽅法不成功
41 method.invoke(per, "sunshine");//使⽤invoke⽅法来调⽤,参数为指定对象,该⽅法传⼊的参数
42 System.out.ReturnType());//获取到该类指定⽅法的返回值类型
43 }
44 @Test
45public void test7()throws Exception{
46 Method method = Method("methodT2", int[].class,String[].class);
47 method.invoke(per, new int[]{1,2},new String[]{"AA","BB"});
48 }
49//获取某个类的main⽅法⽐较特殊也可以说是只要传⼊的参数为单个数组特殊
50//jdk5之后新增特性--可变参数
51//在加载时会将传⼊的数组进⾏拆分,这样就会报错,java.lang.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 = Method("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 flect.Constructor;
2import flect.Field;
3import flect.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) Constructor(null).newInstance(null);// 使⽤反射创建对象
27 }
28// 公有属性
29 @Test
30public void test9() throws Exception {
31// 获取某个属性,参数是属性名
32 Field field = Field("name");
33// 输出属性值,需要传⼊指定对象
34 System.out.(per));
35// 获取属性的类型
36 System.out.Type());
37// 获取多个属性
38 Field[] field1 = Fields();
39// 增强for循环Jdk1.5后的新特性,只适⽤于数组和实现了Iterator的集合
40for (Field str : field1) {
41 System.out.println(str);
42 }
43// 设置属性值
44 field.set(per, "baby");
45 System.out.(per));
46 }
47//私有属性
48 @Test
49public void test10() throws Exception {
50 Field field = DeclaredField("age");
51 field.setAccessible(true);//暴⼒反射
52 System.out.(per));
53 }
54
55 @AfterClass
56public static void afterClass() {
57 System.out.println("===测试完成将对象赋值为null===");
58 }
59 }
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论