java反射
1.什么是java反射
在运行状态中,对于任意一个类,都能够知道这个类的所有方法和属性;对于任何一个对象,都能调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
2.java反射的三种方式
public class Main {
public static void main(String[] args) {
//方式1
Student student = new Student();
Class clazz = student.getClass();
//方式2
Class clazz1 = Student.class;
//方式3
try{
Class clazz2 = Class.forName("com.test.reflect.Student");
}catch (Exception e){
e.printStackTrace();
}
}
}
3.构造函数的反射
@Data
public class Student {
private int stuNo;
private String stuName;
public Student(){
System.out.println("调用公有无参构造函数");
}
public Student(int stuNo){
System.out.println("调用公有的带有一个参数的构造函数");
this.stuNo = stuNo;
}
private Student(int stuNo, String stuName){
System.out.println("调用私有的带有两个参数的构造函数");
this.stuNo = stuNo;
this.stuName = stuName;
}
}
public class Main {
public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {
Class clazz = Student.class;
System.out.println("获取所有的公有构造函数");
Constructor[] constructors = clazz.getConstructors();
for(Constructor constructor : constructors){
System.out.println(constructor);
}
System.out.println("获取所有的包括公有私有默认受保护的构造函数");
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
for(Constructor constructor : declaredConstructors){
System.out.println(constructor);
}
System.out.println("获取公有、无参的构造方法");
Constructor c1 = clazz.getConstructor(null);//传递参数类型
System.out.println("==========>c1=" + c1);
Object object1 = c1.newInstance();
System.out.println("获取带有一个参数的构造方法");
Constructor c2 = clazz.getConstructor(int.class);
System.out.println("==========>c2=" + c2);
//调用构造函数
Object object2 = c2.newInstance(123);
System.out.println("获取带有两个参数的私有构造方法");
Constructor c3 = clazz.getDeclaredConstructor(int.class, String.class);//注意:int不是Integer
System.out.println("==========>c3=" + c3);
//调用构造函数
c3.setAccessible(true);//私有方法暴力访问
Object object3 = c3.newInstance(123, "xiaoming");
}
}
4.属性的反射
@Data
public class Student {
private int stuNo;
private String stuName;
public String address;
}
public class Main {
public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, NoSuchFieldException {
Class clazz = Student.class;
System.out.println("获取所有的变量");
Field[] fields = clazz.getDeclaredFields();
for(Field field : fields){
System.out.println("field:" + field);
}
System.out.println("获取所有的公有的变量");
Field[] fields1 = clazz.getFields();
for(Field field : fields1){
System.out.println("field:" + field);
}
System.out.println("获取某一个public变量");
Field field = clazz.getField("address");
System.out.println("field:" + field);
System.out.println("通过反射修改变量的值");
Student student = new Student();
student.setAddress("西安");
field.set(student, "北京");
System.out.println("student=" + student);
System.out.println("获取某一个private变量");
Field fieldStuNo = clazz.getDeclaredField("stuNo");
System.out.println("fieldStuNo:" + fieldStuNo);
System.out.println("通过反射修改私有变量的值");
Student student1 = new Student();
student1.setStuNo(123);
fieldStuNo.setAccessible(true);//私有方法暴力访问
fieldStuNo.set(student1, 456);
System.out.println("student1=" + student1);
}
}
5.方法的反射
@Data
public class Student {
private void showOne(){
System.out.println("私有的无参方法");
}
public void showThree(int stuNo, String stuName){
System.out.println("公有的有参方法stuNo=" + stuNo + ",stuName=" + stuName);
}
}
public class Main {
public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, NoSuchFieldException {
Class clazz = Student.class;
System.out.println("获取所有声明的方法");
Method[] allMethods = clazz.getDeclaredMethods();
for(Method method : allMethods){
System.out.println(method);
}
System.out.println("获取公有的声明方法");
Method[] methods = clazz.getMethods();
for(Method method : methods){
System.out.println(method);
}
System.out.println("调用私有的无参方法");
Method method = clazz.getDeclaredMethod("showOne");
Object object = clazz.getConstructor().newInstance();
method.setAccessible(true);
method.invoke(object);
System.out.println("调用公有的有参方法");
Method methodTwo = clazz.getMethod("showThree", int.class, String.class);
Object objectTwo = clazz.getConstructor().newInstance();
methodTwo.invoke(objectTwo, 123, "xiaoming");
}
}
6.main方法的反射
public class Student {
public static void main(String[] args) {
System.out.println("开始调用main方法");
}
}
public class Main {
public static void main(String[] args) {
Class clazz = Student.class;
Method method = clazz.getMethod("main", String[].class);
method.invoke(null, (Object) new String[]{"1", "2"});
}
}
7.反射方法的其他使用:
//通过反射越过泛型检查:有一个String泛型的集合,怎样能向这个集合中添加一个Integer类型的值
public class Main {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
List<String> list = new ArrayList<String>();
list.add("123");
list.add("456");
Class clazz = list.getClass();
Method method = clazz.getMethod("add", Object.class);
method.invoke(list, 789);
for(Object object : list){
System.out.println(object);
}
}
}
参考:https://blog.csdn.net/sinat_38259539/article/details/71799078