通过反射可以得到字节码文件中的信息,比如字节码中的属性、方法、构造器等,是与类对应的。
今天学习属性field的一些api。设置一个User类,内容如下:
public class User {
public int num;
private double hight;
protected String cname;
static boolean sex;
private static int age;
}
一、反射属性
先获取字节码文件:
Class cUser = Class.forName("org.example.dao.User");
getFields获取公开的属性,即带有public的
Field[] fields = cUser.getFields();
for (Field f : fields) {
System.out.println(f);
}
输出:public int org.example.dao.User.num
getDeclaredFields()获取所有的属性,无论是私有的还是公开的还是受保护的。返回的是一个field的数组。
Field[] declaredFields = cUser.getDeclaredFields();
for (Field item : declaredFields) {
System.out.println("获取属性全名:" + item);
}
输出结果:
获取属性全名:public int org.example.dao.User.num
获取属性全名:private double
org.example.dao.User.hight获取属性全名:protected java.lang.String
org.example.dao.User.cname获取属性全名:static boolean org.example.dao.User.sex
获取属性全名:private static int org.example.dao.User.age
获取属性全名:float org.example.dao.User.kg
如果你不想输出这么长的名字,可以用getName()获取短名。
Field[] declaredFields = cUser.getDeclaredFields();
for (Field item : declaredFields) {
System.out.println("获取属性简名:" + item.getName());
}
输出结果:
获取属性简名:num
获取属性简名:hight
获取属性简名:cname
获取属性简名:sex
获取属性简名:age
获取属性简名:kg
获取类型名
Field[] declaredFields = cUser.getDeclaredFields();
for (Field item : declaredFields) {
System.out.println("获取属性类型:" + item.getType());
}
输出结果:
获取属性类型:int
获取属性类型:double
获取属性类型:class java.lang.String
获取属性类型:boolean
获取属性类型:int
获取属性类型:float
获取属性修饰符
Field[] declaredFields = cUser.getDeclaredFields();
for (Field item : declaredFields) {
System.out.println("获取修饰符编号:" + item.getModifiers());
}
输出结果:
获取修饰符编号:1
获取修饰符编号:2
获取修饰符编号:4
获取修饰符编号:8
获取修饰符编号:10
获取修饰符编号:0
输出的是一堆修饰符编号,什么都不加 是0 , public 是1 ,private 是 2 ,protected 是 4,static 是 8 ,final 是 16;可以用Modifier.toString()进行转换。
Field[] declaredFields = cUser.getDeclaredFields();
for (Field item : declaredFields) {
System.out.println("获取修饰符名字:" + Modifier.toString(item.getModifiers()));
}
输出结果:
获取修饰符名字:public
获取修饰符名字:private
获取修饰符名字:protected
获取修饰符名字:static
获取修饰符名字:private static
获取修饰符名字:
二、类属性的获取:
Class cUser = Class.forName("org.example.dao.User");
System.out.println("获取字节码文件全名:" + cUser.getName());
System.out.println("获取字节码文件简单名:" + cUser.getSimpleName());
System.out.println("获取字节码文件修饰符:" + Modifier.toString(cUser.getModifiers()));
结果:
获取字节码文件全名:org.example.dao.User
获取字节码文件简单名:User
获取字节码文件修饰符:public
解析:
getName():是获取类的全限定名
getSimpleName():获取类的简单名字
三、以实例对象的方式设置属性值
用newInstance创建实例对象,
public class Client {
public static void main(String[] args) throws Exception {
Class cUser = Class.forName("org.example.dao.User");
// User obj =(User) cUser.newInstance();
Object obj = cUser.newInstance();
}
}
用getDeclaredField获取单个的属性,这里不是getDeclaredFields哈,少了个s。
public class Client {
public static void main(String[] args) throws Exception {
Class cUser = Class.forName("org.example.dao.User");
// User obj =(User) cUser.newInstance();
Object obj = cUser.newInstance();
Field hight = cUser.getDeclaredField("hight");
}
}
获取到属性后,给hight赋值,用hight.set(obj, 178);
hight:是要赋值的属性。
set:设置
obj:是给那个对象赋值
178:要设的属性值
public class Client {
public static void main(String[] args) throws Exception {
Class cUser = Class.forName("org.example.dao.User");
// User obj =(User) cUser.newInstance();
Object obj = cUser.newInstance();
Field hight = cUser.getDeclaredField("hight");
hight.set(obj, 178);
}
}
此时运行一下,发现报错了:
这是因为hight属性是一个私有的,不能设置属性值。
怎么办呢?可以用setAccessible(true);进行强制赋值。
public class Client {
public static void main(String[] args) throws Exception {
Class cUser = Class.forName("org.example.dao.User");
// User obj =(User) cUser.newInstance();
Object obj = cUser.newInstance();
Field hight = cUser.getDeclaredField("hight");
hight.setAccessible(true);
hight.set(obj, 178);
}
}
强制赋值之后就可以了,那我们怎么查看赋值的结果呢?
用hight.get(obj)查看结果:
hight:是要查看的属性
get:查询
obj:查询那个对象的属性值。
public class Client {
public static void main(String[] args) throws Exception {
Class cUser = Class.forName("org.example.dao.User");
// User obj =(User) cUser.newInstance();
Object obj = cUser.newInstance();
Field hight = cUser.getDeclaredField("hight");
System.out.println(hight.getName());
hight.setAccessible(true);
hight.set(obj, 178);
System.out.println(hight.get(obj));
}
}