JavaSE 反射——获取及反编译Field

一、获取Field

  • 获取Java成员变量有两种方式:
    通过getter、setter方法;
    通过反射获取成员变量

1. 常用方法

  • 参考:Field 类常用方法
  • Class.getField(String name);
    返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段
  • Class.getFields();
    返回一个包含某些 Field 对象的数组,该数组包含此 Class 对象所表示的类或接口的所有可访问公共字段
  • Class.getDeclaredField(String name);
    返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段(包括私有成员)
  • Class.getDeclaredFields();
    返回 Field 对象的一个数组,该数组包含此 Class 对象所表示的类或接口所声明的所有字段(包括私有成员)

2. 测试用例

  • 定义一个User类
public class User {
    
    

	public int id;
	
	private String name;
	
	String address;
	
	protected int sno;
	
	public User() {
    
    }
	
	public User(int id, String name, String address, int sno) {
    
    
		super();
		this.id = id;
		this.name = name;
		this.address = address;
		this.sno = sno;
	}

	@Override
	public String toString() {
    
    
		return "User [id=" + id + ", name=" + name + ", address=" + address + ", sno=" + sno + "]";
	}

	@Override
	public int hashCode() {
    
    
		final int prime = 31;
		int result = 1;
		result = prime * result + ((address == null) ? 0 : address.hashCode());
		result = prime * result + id;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + sno;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
    
    
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (address == null) {
    
    
			if (other.address != null)
				return false;
		} else if (!address.equals(other.address))
			return false;
		if (id != other.id)
			return false;
		if (name == null) {
    
    
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (sno != other.sno)
			return false;
		return true;
	}
}
  • 编写测试类
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class ReflectTest {
    
    
	public static void main(String[] args) throws ClassNotFoundException {
    
    
		// 获取整个类
        Class userClass = Class.forName("com.lzj.reflect.pojo.User");

        String className = userClass.getName();
        System.out.println("完整类名:" + className);

        String simpleName = userClass.getSimpleName();
        System.out.println("简易类名:" + simpleName);

        // 获取类中所有的public修饰的Field
        Field[] fields = userClass.getFields();
        System.out.println(fields.length); // 1
        
        // 取出这个Field
        Field f = fields[0];
        // 取出此Field的名字
        String fieldName = f.getName();
        System.out.println(fieldName); // id

        // 获取所有的Field
        Field[] fs = userClass.getDeclaredFields();
        System.out.println(fs.length); // 4
        System.out.println("---------------------");
        
        // 遍历
        for(Field field : fs){
    
    
            // 获取属性的修饰符列表
            int i = field.getModifiers(); // 返回的修饰符是一个数字,每个数字是修饰符的代号
            System.out.println(i);
            System.out.println("=====================");
            // 将代号数字转换成字符串
            String modifierString = Modifier.toString(i);
            System.out.println(modifierString);
            System.out.println("+++++++++++++++++++++");
            
            // 获取属性的类型
            Class fieldType = field.getType();
            // String fName = fieldType.getName();
            String fName = fieldType.getSimpleName();
            System.out.println(fName);
            System.out.println("*********************");
            
            // 获取属性的名字
            System.out.println(field.getName());
        }
	}
}

二、反编译Field

  • 反编译就是把*.class 文件逆向生成*.java文件
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class ReflectTest {
    
    
	public static void main(String[] args) throws Exception {
    
    
        StringBuilder str = new StringBuilder();

        Class userClass = Class.forName("com.lzj.reflect.pojo.User");

        str.append(Modifier.toString(userClass.getModifiers()) + " class " + userClass.getSimpleName() + " {\n");

        Field[] fields = userClass.getDeclaredFields();
        for(Field field : fields){
    
    
            str.append("\t");
            str.append(Modifier.toString(field.getModifiers()));
            str.append(" ");
            str.append(field.getType().getSimpleName());
            str.append(" ");
            str.append(field.getName());
            str.append(";\n");
        }

        str.append("}");
        System.out.println(str);
	}
}

1. 如何防止反编译

  • 隔离Java程序
  • 对Class文件进行加密
  • 代码混淆(将代码转换成功能上等价,但是难于阅读和理解的形式)

猜你喜欢

转载自blog.csdn.net/LvJzzZ/article/details/108700196