• 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调用方法

 public class Demo1 {
@Test
public void fun1() throws Exception {
String className = "cn.jt.User";
Class clazz = Class.forName(className);
Constructor c = clazz.getConstructor(String.class, String.class);
User user = (User)c.newInstance("zhangSan", "123"); //获取名为toString,没有参数的方法
Method method = clazz.getMethod("toString"); //反射调用这个方法,给this赋值为user,没有传递参数,因为这个方法没有参数
String result = (String)method.invoke(user); //打印返回值
System.out.println(result);
}
}
Ø  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读写成员

 public class Demo1 {
@Test
public void fun1() throws Exception {
String className = "cn.jt.User";
Class clazz = Class.forName(className); User user = new User("zhangSan", "123"); //获取名为username的成员变量
Field field1 = clazz.getField("username"); //获取名为password的成员变量
Field field2 = clazz.getField("password"); //获取user对象的username成员变量值,因为field1表示的就是username成员变量
String username = (String)field1.get(user); //获取user对象的password成员变量值,因为field2表示的就是password成员变量
String password = (String)field2.get(user); System.out.println(username + ", " + password); //设置user对象的username成员变量值为liSi
field1.set(user, "liSi"); //设置user对象的password成员变量值为456
field2.set(user, "456"); System.out.println(user);
}
}
Ø  AccessibleObject

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

AccessibleObject最为重要的方法如下:

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

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

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

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

 User.java
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 + "]";
}
} 注意,User类的username和password成员变量为private的,
这时再通过Field来反射操作这两个成员变量就必须先通过setAccessible(true)设置后才行。 public class Demo1 {
@Test
public void fun1() throws Exception {
String className = "cn.jt.User";
Class clazz = Class.forName(className);
User user = new User("zhangSan", "123"); 因为username和password都是私有的成员变量,所以需要使用getDeclaredField()才能获取到。 Field field1 = clazz.getDeclaredField("username");
Field field2 = clazz.getDeclaredField("password"); 设置成员变量是可以访问的,对于私有变量、方法、构造器都必须先调用这个方法后才能操作,不然会抛出异常 field1.setAccessible(true);
field2.setAccessible(true); String username = (String)field1.get(user);
String password = (String)field2.get(user); System.out.println(username + ", " + password); field1.set(user, "liSi");
field2.set(user, "456"); System.out.println(user);
}
}

Summary:

Class  类的反射对象

Constructor  构造器的反射对象

Method表示方法的反射对象

Field  成员的反射对象

最新文章

  1. js控制只能输入数字和控制小数的位数
  2. python 聊天室
  3. 【学习笔记】Y2-1-1 Oracle数据库基础
  4. 1-01Sql Sever 2008的安装
  5. TC SRM 593 DIV2 1000
  6. unity中全屏背景图缩放
  7. POJ 1777 mason素数
  8. JAVA-读取文件部分内容计算HASH值
  9. 使用cocapods报错 [!] Your Podfile has had smart quotes sanitised. To avoid issues in the future, you should not use TextEdit for editing it. If you are not using TextEdit, you should turn off smart quotes
  10. mysql索引优化面试题
  11. 如何使用 Bootstrap 搭建更合理的 HTML 结构
  12. JAVAEE——BOS物流项目05:OCUpload、POI、pinyin4J、重构分页代码、分区添加、combobox
  13. Bzoj1899: [Zjoi2004]Lunch 午餐
  14. sqlserver数据库备份时出现3241问题
  15. gentoo hibernate
  16. 最全的libcurl库资源整理
  17. Python+OpenCV图像处理(十五)—— 圆检测
  18. 浅谈如何避免内存泄漏(out of memory)
  19. Kprobes
  20. webpack 生命周期

热门文章

  1. 溢出文本省略号表示的css实现及polyfill
  2. Hibernate 零配置之Annotation注解
  3. 关于Unity中MonoBehaviour的构造函数
  4. JZOJ6096 森林
  5. 【OCP 12c】最新CUUG OCP-071考试题库(62题)
  6. 【ocp-12c】最新Oracle OCP-071考试题库(40题)
  7. OCP考试题库更新,052最新考题及答案整理-第8题
  8. 打开SQL Server2000企业管理器时候提示“MMC 无法创建管理单元 ”
  9. AngularJS入门讲解2:过滤器和双向绑定
  10. 干货 | Elasticsearch Nested类型深入详解(转)