javafield类_(4)Field类的基本使用和解析

更新时间:2023-07-15 13:06:15 阅读: 评论:0

梦幻校园javafield类_(4)Field类的基本使⽤和解析
上⾯⼀⼩节主要讲解了class的基本⽤法和⼀些⽅法的源码解析,这⼀⼩节主要从讲解字段的基本使⽤,主要从下⾯三个⽅⾯进⾏讲解:
获取字段类型
检索和解析字段修饰符
设置和访问字段的值
字段常见错误⽤法
1.获取字段类型
下⾯的例⼦实现了⼀个类中指定字段的扫描,要得到⼀个指定字段类型,⾸先需要得到字段所在的类的类型信息,然后得到给出字段的名称的信息,然后调⽤Field("字段名称")可以得到字段的信息。
/**
* @Project: jdk
* @description: 类中字段扫描
* @author: sunkang
* @create: 2018-09-27 13:28
* @ModificationHistory who when What
**/
public class FieldSpy {
public boolean[][] b = {{ fal, fal }, { true, true } };
public String name = "Alice";
public List list;
public T val;
public static void args) {
// args = new String[]{Name(),"b"};
args = new String[]{Name(),"val"};
try {
Class> c = Class.forName(args[0]);
Field f = c.getField(args[1]);
System.out.format("Type: %s%n", f.getType()); //getType()返回字段的类型信息
System.out.format("GenericType: %s%n", f.getGenericType());//返回字段的泛型类型信息
// production code should handle the exceptions more gracefully
} catch (ClassNotFoundException x) {
x.printStackTrace();
} catch (NoSuchFieldException x) {
x.printStackTrace();
}
}
}
输出结果为:
Type: class java.lang.Object
GenericType: T
思考 :
1.为什么Type 为Object类的信息呢?
原有的泛型信息会在编译期间进⾏擦除,T会被这个类型的上限进⾏取代,T的类型上限是Object,所以f.getType()为java.lang.Object的类
2.为什么GenericType()可以得到泛型的类型呢?
原因在于getgenerictype()将在类⽂件中查询签名属性,如果属性不存在则调⽤Type()⽅法,对应的源码如下:
public Type getGenericType() {
if (getGenericSignature() != null)
return getGenericInfo().getGenericType();
el
return getType();
}
private String getGenericSignature() {return signature;}
思考⼀下,那么字段的signature的字段信息是怎么设置的,泛型的信息是根据signature来进⾏解析,这⾥涉及的⽐较复杂,这个signature解析出泛型的部分暂时不看。
先看看signature怎么设置的,字段信息是从class对象来的,所以需要找到Field(),对应的源码如下:孕妇装品牌
@CallerSensitive
public Field getField(String name)
throws NoSuchFieldException, SecurityException {
checkMemberAccess(Member.PUBLIC, CallerClass(), true);
平板电脑怎么刷机
Field field = getField0(name); //找到指定的字段
if (field == null) {
throw new NoSuchFieldException(name);
}
return field;
}
private Field getField0(String name) throws NoSuchFieldException {
// Note: the intent is that the arch algorithm this routine
// us be equivalent to the ordering impod by
// privateGetPublicFields(). It fetches only the declared
// public fields for each class, however, to reduce the number
// of Field objects which have to be created for the common
// ca where the field being requested is declared in the
// class which is being queried.
Field res;
// Search declared public fields 从本地声明的开始找
if ((res = archFields(privateGetDeclaredFields(true), name)) != null) { return res;
}
// Direct superinterfaces, recursively //从接⼝找
Class>[] interfaces = getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
Class> c = interfaces[i];
if ((res = c.getField0(name)) != null) {
return res;
}
}
// Direct superclass, recursively
if (!isInterface()) {
捉鸡Class> c = getSuperclass(); //从⽗类找
if (c != null) {
if ((res = c.getField0(name)) != null) {教师节贺卡diy
return res;
}
}
}疑犯追踪第六季
return null;
}
archFields找到指定的字段信息
private static Field archFields(Field[] fields, String name) {
String internedName = name.intern();
for (int i = 0; i < fields.length; i++) {
if (fields[i].getName() == internedName) {//循环字段,然后进⾏名称匹配
return getReflectionFactory().copyField(fields[i]); //这⾥实现了字段的拷贝,关键在这个⽅法,返回的是拷贝后的对象}
}
return null;
}
最终字段的拷贝见下⾯的py()⽅法,signature签名信息是从这⾥开始设置进去的
Field copy() {
// This routine enables sharing of FieldAccessor objects
// among Field objects which refer to the same underlying
// method in the VM. (All of this contortion is only necessary
// becau of the "accessibility" bit in AccessibleObject,
// which implicitly requires that new flect
// objects be fabricated for each reflective call on Class
// objects.)
if ( != null)
throw new IllegalArgumentException("Can not copy a non-root Field");
Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations);//这⾥的signature被设置进来。 = this;
// Might as well eagerly propagate this if already prent
res.fieldAccessor = fieldAccessor;
res.overrideFieldAccessor = overrideFieldAccessor;
return res;
}
2.检索和解析字段修饰符
先给出获取修饰符的字段的例⼦:
猜题游戏/**
* @Project: jdk
* @description: 字段修饰符的测试案例
* @author: sunkang
* @create: 2018-10-05 18:40
* @ModificationHistory who when What
**/
public class FieldModifierTest {
@Deprecated
private volatile int share;
enum Color { BLACK , WHITE }
public static void main(String[] args) {
try {
Class clazz = FieldModifierTest.class;
//得到指定的字段信息
Field field = DeclaredField("share");
//得到所有的修饰符之和,不同的值代表不同修饰符,但是这些值都是进⾏相加的
int modifiers = Modifiers();
/
/Modifier是⼀个⼯具类,toString 表⽰⽣成不同的修饰符
System.out.println("share字段所指定的所有的修饰符:"+String(modifiers)); //判断修饰符是否是Volatile
System.out.println("isVolatile:"+Modifier.isVolatile(modifiers));
//判断修饰符是否是私有的
System.out.println("isPrivate:"+Modifier.isPrivate(modifiers));
//得到字段的注解信息
Deprecated annotation = Annotation(Deprecated.class);
System.out.println("字段的注解信息:"+ annotation.annotationType());
//得到所有声明的字段
Field[] flds = DeclaredFields();
for (Field f: flds ){
System.out.format("%-8s [ synthetic=%-5b enum_constant=%-5b ]%n",
f.isEnumConstant());// f.isEnumConstant()表⽰是否是枚举实例
}
//EnumConstants可以得到⼀个类的枚举实例
System.out.println(Arrays.asList(EnumConstants()));
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
皮肤瘙痒的原因及治疗
输出结果为:
share字段所指定的所有的修饰符:private volatile

本文发布于:2023-07-15 13:06:15,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1082430.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:字段   信息   得到   修饰符   指定
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图