反射剖析
就是在运行中类加载过程把类的信息(方法,构造,属性)存储为Class(注意不是class类)的对象,在这个过程中就破坏了封装,之后就可以获取到类的所有信息。
//下面就是用反射获取类信息的过程
//要剖析的类
package com.it.reflect;
/**
* @Date 2019/8/16 13:51
* @Created by hfh
* @Description TODO
*/
public class Animal {
//属性
public int a;
private int age;
private String name;
private String gender;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//代餐构造
private Animal(int age, String name, String gender) {
this.age = age;
this.name = name;
this.gender = gender;
}
public Animal(int age, String name) {
this.age = age;
this.name = name;
}
//无参构造
public Animal() {
}
//普通方法 无返回值 无参数
public void print() {
System.out.println("姓名:" + name + "年龄“" + age + "性别:" + gender);
}
//代参
public void print(String address) {
System.out.println("姓名:" + name + "年龄“" + age + "性别:" + gender + "地址:" + address);
}
//有返回值的
public String print1() {
return "姓名:" + name + "性别:" + gender;
}
//私有方法
private void print2() {
System.out.println("私有方法");
}
@Override
public String toString() {
return "Animal{" +
"age=" + age +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
//剖析开始啦
package com.it.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @Date 2019/8/16 13:58
* @Created by hfh
* @Description TODO
*/
public class ReflectTest {
public static void main(String[] args) throws Exception{
// getclass();
//getMethod();
getFeild();
}
//获取Class 类的类对象的三种方式
public static void getclass() throws Exception {
//方式一:获取类的类对象 类名.class
Class<Animal> clazz1 = Animal.class;
System.out.println(clazz1.hashCode());
//方式二 根据对象获取
Animal animal = new Animal();
Class<? extends Animal> clazz2 = animal.getClass();
System.out.println(clazz2.hashCode());
//方式三:根据Class.forName
Class<?> clazz3 = Class.forName("com.it.reflect.Animal");//获得的是类的类对象
System.out.println(clazz3.hashCode());
}
//获取破解类的方法
public static void getMethod() throws Exception{
//获得的是类的类对象 Class 类的 类对象就是Animal对象(此处把Animal类当做对象对待)
Class<?> clazz = Class.forName("com.it.reflect.Animal");
//1:类对象获取 所有公开方法方法 包括他的父类方法 不包括子类方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
//System.out.println(method);
}
//2:获取私有方法
Method print2 = clazz.getDeclaredMethod("print2");
System.out.println(print2);
//3:获取无参无返回值方法 并调用
Method print = clazz.getMethod("print");//获取方法
Object o = clazz.newInstance();//创建类对象的对象
print.invoke(o);//调用方法
//4:获取无返回值 有参方法
Method print1 = clazz.getMethod("print", String.class);
print1.invoke(o, "北京");
//5:有返回值无参方法
System.out.println("5:有返回值无参方法");
Method print11 = clazz.getMethod("print1");
String s = (String )print11.invoke(o);
System.out.println(s);
System.out.println("------------无参构造----------");
Constructor<?> constructor = clazz.getConstructor();
System.out.println(constructor);
System.out.println("---------有参构造-----------------");
Constructor<?> constructor1 = clazz.getConstructor(int.class, String.class);
System.out.println(constructor1);
System.out.println("---------有参私有构造-----------------");
Constructor<?> constructor2 = clazz.getDeclaredConstructor(int.class, String.class, String.class);
System.out.println(constructor2);
System.out.println("-----------------破解私有构造-----------------------");
constructor2.setAccessible(true);//破解私有构造
Object o1 = constructor2.newInstance(12,"jkf","jk");
//私有构造调用方法
print.invoke(o1);
}
//获取公开属性,私有属性,修改私有属性
public static void getFeild()throws Exception {
//创建类的类对象
Class<?> clazz = Class.forName("com.it.reflect.Animal");
System.out.println("----------------所有属性-------------------");
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
System.out.println("-------------修改私有属性-------------------------");
Method setAge = clazz.getMethod("setAge", int.class);
Object o = clazz.newInstance();
Field age = clazz.getDeclaredField("age");
age.setAccessible(true);
setAge.invoke(o,45);
Method print = clazz.getMethod("print");
print.invoke(o);
}
}
//有女生想和在下探讨java的可以联系:13386609751