1.获取类的字节码对象
//获取类的字节码对象
public class Demo1 {public static void main(String[] args) throws ClassNotFoundException {//方式1:类名.ClassClass<?> 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...有参构造方法");}@Overridepublic 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对象的成员变量赋值为valuef2.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();参数中执行方法