1.获取类的字节码对象
//获取类的字节码对象
public class Demo1 {
public static void main(String[] args) throws ClassNotFoundException {
//方式1:类名.Class
Class<?> clazz1 = Student.class;
//方式2:对象名.getClass()
Student student = new Student();
Class<?> clazz2 = student.getClass();
//方式3:Class.forName("类的全路径名")
Class<?> clazz3 = Class.forName("com.itheima1.Student");
System.out.println(clazz1);
System.out.println(clazz1 == clazz2);
System.out.println(clazz2 == clazz3);
}
}
2.获取Constructor【构造方法】对象
学生类
public class Student {
private String name;
private int age;
//公共的无参构造方法
public Student() {
System.out.println("public...Student...无参构造方法");
}
//公共的有参构造方法
public Student(String name, int age) {
System.out.println("name的值为:" + name + "age的值为" + age);
System.out.println("public...Student...有参构造方法");
}
//私有的有参构造方法
private Student(String name) {
this.name= name ;
System.out.println("name的值为:" + name);
System.out.println("private...Student...有参构造方法");
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
获取Constructor对象的方法
//获取Constructor对象
public class Demo1 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
//首先得到Class对象再调用方法
Class<?> clazz = Class.forName("com.itheima2.Student");
//Constructor<T> getConstructor (class<?>... parameterTypes):返回单个公共构造方法对象【只能返回公共的,默认的等也不行】
//Constructor<?> constructor = clazz.getConstructor();
//constructor<T> getDeclaredConstructor (class<?>... parameterTypes):返回单个构造方法对象【可以返回私有的】
Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(String.class, int.class);
System.out.println(declaredConstructor);
//Constructor<?>[] getConstructors ():返回所有公共构造方法对象的数组
Constructor<?>[] constructors = clazz.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
//Constructor<?>[] getDeclaredConstructors ():返回所有构造方法对象的数组
//Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
}
}
打印结果:
-------------------------------------------------------------------------------------
public com.itheima2.Student(java.lang.String,int)
public com.itheima2.Student(java.lang.String,int)
public com.itheima2.Student()
2.1 Constructor对象的使用
根据指定的构造方法创建对象:
Class.newInstance();只能反射无参的构造器,需要构造器可见;
Constructor.newInstance();可以反射任何构造器,可以反射私有构造器
//反射获取Constructor对象并使用
//T newInstance (object. . . initargs):根据指定的构造方法创建对象
public class Demo2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//1.获取Class对象
Class<?> clazz = Class.forName("com.itheima2.Student");
//2.获取构造方法对象【四种方法】
Constructor<?> constructor1 = clazz.getDeclaredConstructor(String.class);
//访问私有【其他修饰都能使用】的构造不能直接使用,getDeclaredConstructor()只能做访问
//constructor.setAccessible(true):在创建学生对象之前临时取消访问检查【暴力反射】
constructor1.setAccessible(true);
//3.利用newInstance创建Student的对象
Student student = (Student) constructor1.newInstance("张三");
System.out.println(student);
System.out.println("---------------------------------------------------------");
//简写格式【不能获取私有方法,其他都可,默认访问空参构造】
//1.获取Class对象
Class<?> clazz1 = Class.forName("com.itheima2.Student");
//2.在Class类中,有一个newInstance方法,可以利用空参直接创建一个对象【已过时,做了解】
Student student1 = (Student) clazz1.newInstance();
System.out.println(student1);
}
}
c
name的值为:张三
private...Student...有参构造方法
Student{name='张三', age=0}
---------------------------------------------------------
public...Student...无参构造方法
Student{name='null', age=0}
3.获取Field【成员变量】对象
学生类
public class Student {
public String name;
public int age;
public String gender;
private int money = 300;
}
获取Field【成员变量】对象的方法
//获取Field【成员变量】对象的方法
public class Demo1 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class<?> clazz = Class.forName("com.itheima4.Student");
//Field[] getFields ():返回所有公共成员变量对象的数组
//Field[] fields = clazz.getFields();
//Field[] getDeclaredFields ():返回所有成员变量对象的数组
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
// Field getField (string name):返回单个公共成员变量对象
// 想要获取的成员变量必须是真实存在的
//且必须是public修饰的
Field f1 = clazz.getField("name");
System.out.println(f1);
// Field getDeclaredField (string name):返回单个成员变量对象
Field f2 = clazz.getDeclaredField("money");
System.out.println(f2);
}
}
打印结果:
-------------------------------------------------------------------------------------
public java.lang.String com.itheima4.Student.name
public int com.itheima4.Student.age
public java.lang.String com.itheima4.Student.gender
private int com.itheima4.Student.money
public java.lang.String com.itheima4.Student.name
private int com.itheima4.Student.money
3.1 Field对象的使用
根据指定的构造方法创建对象:
void set (object obj, object value):给obj对象的成员变量赋值为value【如果私有则需要暴力反射】
object get (object obj)返回由该 Field表示的字段在指定对象上的值
//利用Field对象,获取值或者修改值
public class Demo2 {
public static void main(String[] args) throws ReflectiveOperationException {
// 1.获取class对象
Class<?> clazz = Class.forName("com.itheima4.Student");
//2.获取name这个Field对象
Field f1 = clazz.getDeclaredField("name");
Field f2 = clazz.getDeclaredField("age");
Field f3 = clazz.getDeclaredField("money");
f3.setAccessible(true);
f1.setAccessible(true);//由于私有则需要暴力反射[在对象创建之前]
//创建学生类的对象【如果空参构造私有,则要对成员方法暴力反射】
Student student = (Student) clazz.getConstructor().newInstance();
//3.利用set方法进行赋值
//void set (object obj, object value):给obj对象的成员变量赋值为value
f2.set(student, 20);
f1.set(student, "张三");//等价于obj.setNome("张三");
//4.获取属性值
//object get (object obj)返回由该 Field表示的字段在指定对象上的值
System.out.println(f1.get(student));
System.out.println(f2.get(student));
System.out.println(f3.get(student));
}
}
打印结果:
-------------------------------------------------------------------------------------
张三
20
300
4 获取Method【成员方法】对象
学生类
public class Student {
//有一个参数的show方法
public void show(String n) { System.out.println("show..." + n); }
//有两个参数的show方法
private void show(String n, int m) {
System.out.println("show..." + n +"..."+ m);
}
//有两个参数,有返回值的方法
public int sum(int n, int m) {
return m + n;
}
}
反射获取学生类成员方法对象
<font color ="sky bule">反射获取Method【成员方法】对象
public class Demo1 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
Class<?> clazz = Class.forName("com.itheima5.Student");
//Method[] getMethods ():返回所有公共成员方法对象的数组,包括继承的
/*Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
}*/
//Method[] getDeclaredMethods ():返回所有成员防法对象的数组,不包括继承的
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
//Method getMethod (string name,class<?>... parameterTypes) :返回单个公共成员方法对象
//Method getDeclaredMethod (string name,Class<?>... parameterTypes):返回单个成员方法对象
Method show = clazz.getDeclaredMethod("show", String.class, int.class);
System.out.println(show);
}
}
打印结果:
-------------------------------------------------------------------------------------
public int com.itheima5.Student.sum(int,int)
public void com.itheima5.Student.show(java.lang.String)
private void com.itheima5.Student.show(java.lang.String,int)
private void com.itheima5.Student.show(java.lang.String,int)
4.1 Method对象的使用
method.invoke(student, 200, 100);
//反射获取成员方法使用
public class Demo2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取类的字节码文件
Class<?> clazz = Class.forName("com.itheima5.Student");
//创建一个学生对象【调用方法使用】
Student student = (Student) clazz.getConstructor().newInstance();
//获取一个参数的show方法
Method m1 = clazz.getMethod("show" , String.class);
//System.out.println(m1);
//执行
m1.invoke(student,"hahah");//等价于obj.show (" hahah");
//获取两个参数的show方法
Method m2 = clazz.getDeclaredMethod("show", String.class, int.class);
//System.out.println(m2);
m2.setAccessible(true);
//执行
m2.invoke(student,"hehe",100);//等价于obj.show ("hehe",100);
//获取两个int参数的sum方法[名称参数必须一致,不能少]
Method m3 = clazz.getMethod("sum",int.class,int.class);
//System.out.println(m3);
//执行
int sum = (int) m3.invoke(student, 200, 100);
System.out.println(sum);
}
}
打印结果:
-------------------------------------------------------------------------------------
show...hahah
show...hehe...100
300
5. 思路总结
<1>获取Constructor对象
1.创建Class方法【Class.forName(“类的全路径名”)】—通用
2.调用Class获取Constructor对象方法
先看修饰符
如果需要访问私有,则用带Declared的方法
否则两种类型的方法都可以使用
3.访问单个构造:看参数类型和个数填写方法参数得到Constructor对象
访问多个构造:直接调用方法得到Constructor对象
4.得到Constructor对象后使用
Class.newInstance();只能反射无参的构造器,需要构造器非私有;
Constructor.newInstance();可以反射任何构造器,可以反射私有构造器【创建学生对象前加取消访问检查方法】
<2>Constructor.newInstance()得到的对象传递到 Field对象调用的set();get();参数中执行方法
<3>Constructor.newInstance()得到的对象传递到Method对象调用的invoke();参数中执行方法