4Java反射与泛型——1反射——2访问字段(廖雪峰)

1field(字段)

  • getField(name): 获取某个public的field(包括父类),在调用getField()方法时,如果根据给定的方法参数没有找到对应的变量,那么就会抛出NoSuchFieldException
  • getDeclaredField(name): 获取当前类的某个field(不包括父类)
  • getFields(): 获取所有public的field(包括父类)
  • getDeclaredFields(): 获取当前类的所有field(不包括父类)

Field对象包含一个field的所有信息:

  • getName():通过调用Field对象的getName()方法获取它的变量名称
  • getType():通过调用Field对象getType()方法来获取一个变量的类型(如String, int等等)
  • getModifiers():获取修饰符,即public/private/static等修饰符的使用状况,还可以使用Modifier类中的isPublic、isPrivateisFinal判断方法或构造器是否是public、privatefinal
Integer n = new Integer(123);
Class cls = n.getClass();
Field[] fs = cls.getFields();
for (Field f : fs) {
    f.getName(); // field name
    f.getType(); // field type
    f.getModifiers(); // modifiers
}

获取field的值:

  • get(Object)获取一个实例的该字段的值
Integer n = new Integer(123);
Class cls = n.getClass();
Field f = cls.getDeclaredField("value");
f.get(n);//123,相当于n.value

设置field的值:

  • set(Object,Object)设置一个实例的该字段的值
Integer n = new Integer(123);
Class cls = n.getClass();
Field f = cls.getDeclaredField("value");
f.set(n,456);//相当于n.value = 456

2实例演示

public class Main {
	
    public static void main(String[] args) throws Exception{
	Student s = new Student();
	Class cls = s.getClass();
	Field f = cls.getDeclaredField("address");
	//Field f = cls.getDeclaredField("number");//可以获取静态字段number
	//printFieldInfo(f);
	//setAccessible()可以强制变为可以访问
	//setAccessible(true/false):表示启用和禁用安全检查的开关。
	//当值为true时,指反射对象在使用时应该取消java语言访问检查
	//值为false则只是反射的对象应该试试java语言访问检查。
	//当值 设置为true时,不接受检查,可以提高反射的运行速度。
	f.setAccessible(true);
	System.out.println(f.get(s));//获取field的值
	//System.out.println(f.get(null));//静态字段不需要获取实例,传入null
	f.set(s,"shanghai");//设置field的值
	//f.set(null,123);//静态字段不需要获取实例,传入null
	s.hello();
    }

    static void printFieldInfo(Field f) {
	// TODO Auto-generated method stub
	System.out.println("field name:" + f.getName());
	System.out.println("field type:" + f.getType());
	System.out.println("field modifier:" + f.getModifiers());
	System.out.println("is public?" + Modifier.isPublic(f.getModifiers()));
	System.out.println("is protected?" + Modifier.isProtected(f.getModifiers()));
	System.out.println("is private?" + Modifier.isPrivate(f.getModifiers()));
	System.out.println("is static?" + Modifier.isStatic(f.getModifiers()));
	System.out.println("is final?" + Modifier.isFinal(f.getModifiers()));
    }

}
public class Person {
    public int age;

    public int getAge() {
	return age;
    }

    public void setAge(int age) {
	this.age = age;
    }		
}
public class Student extends Person implements Hello{
    public static int number = 0;
    public String name;
    private String address = "beijing";
    public Student() {
	this("unNamed");
    }
    public Student(String name) {
	this.name = name;
    }
    public void hello() {
	System.out.println("Hi, "+name+" from " +address +"!");
    }
}
public interface Hello {
    public void hello();
}

3SecurityManager

setAccessible(true)可能会失败:

  • 定义了SecurityManager
  • SecurityManager的规则阻止对该Field设置accessible:例如,规则应用于所有java和javax开头的package的类

4总结

  • Field对象封装了字段的所有信息
  • 通过Class实例的方法可以获取Field实例:getField/getFields/getDeclaredField/getDeclaredFields
  • 通过Field实例可以获取字段信息:getName/getType/getModifiers
  • 通过Field实例可以读取或设置某个对象的字段:get(Object instance)/set(Object instance,Object fieldValue)
  • 通过设置setAccessible(true)来访问非public字段
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页