什么是反射?
可以从类里面将该类的成员方法成员变量,构造方法的信息给拿出来
使用可以获取成员变量,构造方法,成员方法的所有信息.
学习反射应该学习如何获取和解剖
获取class对象的三种方式
-
在源代码阶段使用Class.forName("全类名");(最常用)
-
在加载阶段使用A.class(一般更多是当作参数传递)
-
在运行阶段使用对象.getClass();(已经有了这个类的对象才能使用)
代码演示
public class MyReflectDemo01 { public static void main(String[] args) throws ClassNotFoundException { //1.第一种方式 //全类名:包名+类名 Student Class clazz = Class.forName("Student"); //打印 System.out.println(clazz); //第二种方式 Class clazz2 = Student.class; //打印 System.out.println(clazz2); System.out.println(clazz == clazz2);//两个获取的是一个对象 //第三种方式 Student s = new Student(); Class clazz3 = s.getClass(); System.out.println(clazz3); //获取的字节码文件对象是一样的 System.out.println(clazz3 == clazz2); System.out.println(clazz2 == clazz); } }
下面是一个标准的Java类
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; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
利用反射获取构造方法
在Java当中万物皆可对象,所以如图所示: Class有对象,构造方法有对象,成员变量和成员方法也有对象
- 返回所有public修饰的构造方法
- 返回所有的构造方法
- 返回单个的public修饰的构造方法
- 返回单个的构造方法
一个Student类
public class Student {
private String name;
private int age;
private Student(int age) {
this.age = age;
}
private Student(String name) {
this.name = name;
}
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
反射的各种方法
import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;
public class MyReflectDemo02 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
//获取class字节码文件对象
Class clazz = Class.forName("Student");
//获取public构造方法
/*
Constructor[] cons =clazz.getConstructors();
for (Constructor con : cons) {
System.out.println(con);
}
*/
//获取所有构造方法
// Constructor[] con1 =clazz.getDeclaredConstructors();
// for (Constructor con : con1) {
// System.out.println(con);
// }
//获取单个构造方法
// Constructor con1 = clazz.getDeclaredConstructor();
// System.out.println(con1);
// //向里面传递的是字节码文件
// Constructor con2 = clazz.getDeclaredConstructor(String.class);
// System.out.println(con2);
// Constructor con3 = clazz.getDeclaredConstructor(int.class);
// System.out.println(con3);
Constructor con4 = clazz.getDeclaredConstructor(String.class, int.class);
// System.out.println(con4);
// int modifiers = con4.getModifiers();//可以获取权限修饰符
// System.out.println(modifiers);
// Student stu = new Student();
// Parameter[] parameters = con4.getParameters();
// for (Parameter parameter : parameters) {
// System.out.println(parameter);
// }
}
}
使用反射创建对象
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;
public class MyReflectDemo02 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//获取class字节码文件对象
Class clazz = Class.forName("Student");
Constructor con3 = clazz.getDeclaredConstructor(String.class);
//暴力反射:临时取消权限校验
con3.setAccessible(true);
Student stu = (Student) con3.newInstance("张三");//本身为private修饰
System.out.println(stu);
}
}
反射获取成员变量
一个Student类
public class Student {
private String name;
private int age;
public String gender;
public Student() {
}
public Student(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
使用反射获取成员变量之后的各种操作
import java.lang.reflect.Field;
public class MyReflectDemo01 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
//1.获取class字节码文件的对象
Class clazz = Class.forName("Student");
//2.获取成员变量
// Field[] fields = clazz.getFields();
//获取所有成员变量
// Field[] fields = clazz.getDeclaredFields();
// for (Field field : fields) {
// System.out.println(field);
// }
//获取单个public成员变量
// Field gender = clazz.getField("gender");
// System.out.println(gender);
// 获取单个成员变量
Field name = clazz.getDeclaredField("name");
System.out.println(name);
//获取权限修饰符(也是int类型整数)
int modifiers = name.getModifiers();
System.out.println(modifiers);
//获取变量名
String n = name.getName();
System.out.println(n);
//获取成员变量数据类型
Class<?> type = name.getType();
System.out.println(type);
//获取成员变量记录的值
Student s = new Student("zhangsan", 23, "男");
name.setAccessible(true);//临时取消访问权限
String value = (String) name.get(s);
System.out.println(value);
//修改对象里面的值
name.set(s, "lisi");
System.out.println(s);
}
}
反射获取成员方法
一个Student类
import java.io.IOException;
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;
}
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 String eat(String something) throws IOException, NullPointerException {
System.out.println("在吃" + something);
return "奥里给";
}
private String eat(String something, int a) {
System.out.println("在吃" + something);
return "奥里给";
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
使用反射调用成员方法的各种操作
import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
public class MyReflectDemo03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//1.获取字节码文件对象
Class clazz = Class.forName("Student");
//2.获取里面所有的方法对象(包含父类所有的公共方法)
// Method[] methods = clazz.getMethods();
// for (Method method : methods) {
// System.out.println(method);
// }
//获取里面所有的方法对象(不可获取父类的公共方法),但是可以获取本类中私有的方法
// Method[] methods = clazz.getDeclaredMethods();
// for (Method method : methods) {
// System.out.println(method);
// }
//获取指定的单一方法
Method m = clazz.getDeclaredMethod("eat", String.class);
System.out.println(m);
//获取方法修饰符
int modifiers = m.getModifiers();
System.out.println(m);
//方法的名字
String name = m.getName();
System.out.println(name);
//获取方法的形参
Parameter[] parameters = m.getParameters();
for (Parameter parameter : parameters) {
System.out.println(parameter);
}
//获取方法抛出的异常
Class[] exceptionTypes = m.getExceptionTypes();
for (Class exceptionType : exceptionTypes) {
System.out.println(exceptionType);
}
//方法运行 invoke方法
Student s = new Student();
//参数1:表示方法的调用者
//参数2:表示在调用方法的时候传递的实际参数
m.setAccessible(true);
m.invoke(s, "汉堡");
//如果方法带返回值的话
Object result = m.invoke(s, "汉堡包");
System.out.println(result);
}
}
标签:JAVA,String,--,age,Student,println,异常,public,name
From: https://www.cnblogs.com/harper886/p/17740248.html