目录
1.获取class对象的三种方式
case1:Class.forName("全类名");--->源代码阶段(常用)
case2:类名.class;-----》加载阶段(编译阶段)(一般更多当作参数进行传递)
case3:对象.getClass();-----》运作阶段(已经有了这个类的对象时才可以使用)
以Student类为例:
package com.hb.relflect;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
以下代码为三种使用方式:
package com.hb.relflect;
public class MyReflect1 {
public static void main(String[] args) throws ClassNotFoundException {
//1.第一种方式
//全类名=包名+类名
Class<?> aClass = Class.forName("com.hb.relflect.Student");
//2.第二种方式
Class<Student> studentClass = Student.class;
//3.第三种方式
Student student=new Student();
Class class3 =student.getClass();
}
}
2.构造方法的获取
2.1.见下面代码
返回public修饰的构造方法。
package com.hb.relflect;
import java.lang.reflect.Constructor;
public class MyReflect1 {
public static void main(String[] args) throws ClassNotFoundException {
//1.获取字节码文件对象
//全类名=包名+类名
Class<?> aClass = Class.forName("com.hb.relflect.Student");
//2.获取构造方法
Constructor[] cons = aClass.getConstructors();
for(Constructor con:cons){
System.out.println(con);
}
}
}
运行结果:
2.2.获取所有的构造方法,无论公有还是私有。
获取所有的构造方法,无论公有还是私有。
用于测试Student类
package com.hb.relflect;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
获取所有构造方法数组:
package com.hb.relflect;
import java.lang.reflect.Constructor;
public class MyReflect1 {
public static void main(String[] args) throws ClassNotFoundException {
//1.获取字节码文件对象
//全类名=包名+类名
Class<?> aClass = Class.forName("com.hb.relflect.Student");
//2.获取构造方法
Constructor[] cons = aClass.getDeclaredConstructors();
for(Constructor con:cons){
System.out.println(con);
}
}
}
运行结果:
2.3.获取单个构造方法
见下面代码及运行结果:
代码:
运行结果:
2.4获取构造方法的权限修饰符
代码:
运行结果:1-》public
2->private
详细见JDK api文档中的常量字段值的reflect部分
2.5获取构造方法的参数
示例:
运行结果:
2.6 获取构造方法,并利用构造方法创建对象
情况一:构造函数是public修饰时。
示例:
运行结果:
情况二:构造函数为私有(private)时
相关代码:
Student类中的构造函数
利用该构造函数创建对象:
运行结果:
为什么会报错?
注意:
aClass.getDeclaredConstructor()方法只是提供一个可读功能,并未实际开放权限。
要想利用私有构造方法创建对象,应该当开放权限。
所以,代码应作如下改动:(下面这种方式也叫暴力反射)
运行结果:
3.利用反射获取成员变量
这个和获取构造函数的规律相似。这里不做详细的解释
情况一:获取所有的public(公共)修饰的成员变量。
情况二: 获取所有的成员变量
情况三: 获取单个的成员变量
公有的成员变量可以用如下的方法进行获取,但是私有的采用如下操作会报错,见下图:
此时,应当调用getDeclaredField()方法进行获取。
3.1获取成员变量的记录的值
这里注意,age为私有成员变量。
3.2修改成员变量记录的值
4.利用反射获取成员方法
以Student类为例:
package com.hb.relflect;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
private Student(int age,String name){
this.age=age;
this.name=name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void sleep(){
System.out.println("睡觉");
}
private void eat(String sth){
System.out.println("在吃"+sth);
}
}
4.1获取所有public修饰的方法(不包括构造函数)
运行结果:(没有eat()函数)
4.2 获取所有成员方法(不能获取父类的,但能获取本类中的私有方法)
运行结果:
4.4获取单个成员方法(包括private)
4.5方法的运行(利用invoke(),详见动态代理)