Java reflect 反射 2

java

  • Constructor

Constructor表示一个类的构造器。即构造器的反射对象!

它是Class的一个组成部门,所以需要先得到Class,再通过Class的方法得到Constructor

1获取Constructor对象

获取Construcator对象需要使用Class对象,下面API来自Class类:

l  Constructor getConstructor(Class<?>… parameterTypes):通过指定的参数类型获取公有构造器反射对象;

l  Constructor[] getConstructors():获取所有公有构造器对象;

l  Constructor getDeclaredConstructor(Class… parameterTypes):通过指定参数类型获取构造器反射对象。可以是私有构造器对象;

l  Constructor[] getDeclaredConstructors():获取所有构造器对象。包含私有构造器;

2 Construcator类常用方法

l  String getName():获取构造器名;

l  Class getDeclaringClass():获取构造器所属的类型;

l  Class[] getParameterTypes():获取构造器的所有参数的类型;

l  Class[] getExceptionTypes():获取构造器上声明的所有异常类型;

l  T newInstance(Object… initargs):通过构造器反射对象调用构造器。

3 练习:通过Construcator创建对象

public class Demo1 {

@Test

public void fun1() throws Exception {

String className = "cn.itcast.User";

Class clazz = Class.forName(className);

//通过参数类型来获取构造器,即获取两个String类型参数的构造器反射对象。

Constructor c = clazz.getConstructor(String.class, String.class);

//通过构造器反射对象来调用构造器,并传递参数给构造器

User user = (User)c.newInstance("zhangSan", "123");

System.out.println(user);

}

}

public class User {

private String username;

private String password;

public User() {

}

public User(String username, String password) {

this.username = username;

this.password = password;

}

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

@Override

public String toString() {

return "User [username=" + username + ", password=" + password + "]";

}

}

  • Method 表示成员方法的类

1获取Method

获取Method需要通过Class对象,下面是Class类的API:

l  Method getMethod(String name, Class… parameterTypes):本类 父类 公共方法  通过方法名和方法参数类型获取方法反射对象

                                                                   包含父类中声明的公有方法,但不包含所有私有方法;

l  Method[] getMethods():本类 父类 所有公共方法 获取所有公有方法,包含父类中的公有方法,但不包含任何私有方法;

l  Method getDeclaredMethod(String name, Class… parameterTypes):本类所有方法 通过方法名和方法参数类型获取本类中声明的方法的反射对象

                                                                             包含本类中的私有方法,但不包含父类中的任何方法;

l  Method[] getDeclaredMethods():本类所有方法  获取本类中所有方法,包含本类中的私有方法,但不包含父类中的任何方法。

2  Method常用方法

l  String getName():获取方法名;

l  Class getDeclaringClass():获取方法所属的类型;

l  Class[] getParameterTypes():获取方法的所有参数的类型;

l  Class[] getExceptionTypes():获取方法上声明的所有异常类型;

l  Class getReturnType():获取方法的返回值类型;

l  Object invoke(Object obj, Object… args):通过方法反射对象调用方法

                               如果当前方法是实例方法,那么当前对象就是obj,

                               如果当前方法是static方法,那么可以给obj传递null。args表示是方法的参数;

3 练习:通过Method调用方法

 1 public class Demo1 {

2 @Test

3 public void fun1() throws Exception {

4 String className = "cn.jt.User";

5 Class clazz = Class.forName(className);

6 Constructor c = clazz.getConstructor(String.class, String.class);

7 User user = (User)c.newInstance("zhangSan", "123");

8

9 //获取名为toString,没有参数的方法

10 Method method = clazz.getMethod("toString");

11

12 //反射调用这个方法,给this赋值为user,没有传递参数,因为这个方法没有参数

13 String result = (String)method.invoke(user);

14

15 //打印返回值

16 System.out.println(result);

17 }

18 }

Ø  Field

Field表示类的成员变量,可以是实例变量,也可以是静态变量。

1 获取Field对象

获取Field对象需要使用Class对象,下面是Class类的API:

l  Field getField(String name):通过名字获取公有成员变量的反射对象,包含父类中声明的公有成员变量;

l  Field[] getFields():获取所有公有成员变量反射对象,包含父类中声明的公有成员变量;

l  Field getDeclaredField(String name):通过名字获取本类中某个成员变量,包含本类的private成员变量,但父类中声明的任何成员变量都不包含;

l  Field[] getDeclaredFields():获取本类中声明的所有成员变量,包含private成员变量,但不包含父类中声明的任何成员变量;

2 Field类的常用方法

l  String getName():获取成员变量名;

l  Class getDeclaringClass():获取成员变量所属的类的类型;

l  Class getType():获取当前成员变量的类型;

l  Object get(Object obj):获取obj对象的成员变量的值;

l  void set(Object obj, Object value):设置obj对象的成员变量值为value;

3 练习:通过Field读写成员

 1 public class Demo1 {

2 @Test

3 public void fun1() throws Exception {

4 String className = "cn.jt.User";

5 Class clazz = Class.forName(className);

6

7 User user = new User("zhangSan", "123");

8

9 //获取名为username的成员变量

10 Field field1 = clazz.getField("username");

11

12 //获取名为password的成员变量

13 Field field2 = clazz.getField("password");

14

15 //获取user对象的username成员变量值,因为field1表示的就是username成员变量

16 String username = (String)field1.get(user);

17

18 //获取user对象的password成员变量值,因为field2表示的就是password成员变量

19 String password = (String)field2.get(user);

20

21 System.out.println(username + ", " + password);

22

23 //设置user对象的username成员变量值为liSi

24 field1.set(user, "liSi");

25

26 //设置user对象的password成员变量值为456

27 field2.set(user, "456");

28

29 System.out.println(user);

30 }

31 }

Ø  AccessibleObject

AccessibleObject类是Constructor、Method、Field三个类的父类。

AccessibleObject最为重要的方法如下:

l  boolean isAccessible():判断当前成员是否可访问;

l  void setAccessible(boolean flag):设置当前成员是否可访问。

                                               当设置该参数为true时,那么private的成员、方法、构造器就都可以操作了。

当Constructor、Method、Field为私有时,如果我们想反射操作,那么就必须先调用反射对象的setAccessible(true)方法,然后才能操作。

 1 User.java

2 public class User {

3 private String username;

4 private String password;

5

6 public User() {

7 }

8

9 public User(String username, String password) {

10 this.username = username;

11 this.password = password;

12 }

13

14 public String getUsername() {

15 return username;

16 }

17

18 public void setUsername(String username) {

19 this.username = username;

20 }

21

22 public String getPassword() {

23 return password;

24 }

25

26 public void setPassword(String password) {

27 this.password = password;

28 }

29

30 @Override

31 public String toString() {

32 return "User [username=" + username + ", password=" + password + "]";

33 }

34 }

35

36 注意,User类的username和password成员变量为private的,

37 这时再通过Field来反射操作这两个成员变量就必须先通过setAccessible(true)设置后才行。

38

39

40 public class Demo1 {

41 @Test

42 public void fun1() throws Exception {

43 String className = "cn.jt.User";

44 Class clazz = Class.forName(className);

45 User user = new User("zhangSan", "123");

46

47 因为username和password都是私有的成员变量,所以需要使用getDeclaredField()才能获取到。

48

49 Field field1 = clazz.getDeclaredField("username");

50 Field field2 = clazz.getDeclaredField("password");

51

52 设置成员变量是可以访问的,对于私有变量、方法、构造器都必须先调用这个方法后才能操作,不然会抛出异常

53

54 field1.setAccessible(true);

55 field2.setAccessible(true);

56

57 String username = (String)field1.get(user);

58 String password = (String)field2.get(user);

59

60 System.out.println(username + ", " + password);

61

62 field1.set(user, "liSi");

63 field2.set(user, "456");

64

65 System.out.println(user);

66 }

67 }

Summary:

Class  类的反射对象

Constructor  构造器的反射对象

Method表示方法的反射对象

Field  成员的反射对象

 

 

以上是 Java reflect 反射 2 的全部内容, 来源链接: utcz.com/z/391082.html

回到顶部