我正在做大学项目.
我需要从课堂上获得所有领域.甚至私人和继承.我试图获取所有声明的字段,然后转换为超类并重复.我的代码片段:
private void listAllFields(Object obj) {
List<Field> fieldList = new ArrayList<Field>();
while (obj != null) {
fieldList.addAll(Arrays.asList(obj.getClass().getDeclaredFields()));
obj = obj.getClass().getSuperclass().cast(obj);
}
// rest of code
Run Code Online (Sandbox Code Playgroud)
但它不起作用.tmpObj在铸造之后仍然是同一个类(不是超类).
我将不胜感激任何帮助如何解决铸造问题,或如何以不同的方式检索这些字段.
问题不是获取字段的访问权限,而是获取字段的名称!
我这样管理它:
private void listAllFields(Object obj) {
List<Field> fieldList = new ArrayList<Field>();
Class tmpClass = obj.getClass();
while (tmpClass != null) {
fieldList.addAll(Arrays.asList(tmpClass .getDeclaredFields()));
tmpClass = tmpClass .getSuperclass();
}
// rest of code
Run Code Online (Sandbox Code Playgroud)
Sea*_*oyd 82
obj = obj.getClass().getSuperclass().cast(obj);
Run Code Online (Sandbox Code Playgroud)
这条线不符合您的预期.转换Object实际上并没有改变它,它只是告诉编译器将其视为其他东西.
例如,你可以投出List的Collection,但它仍然会保持一个List.
但是,通过超类循环访问字段可以正常工作而不需要强制转换:
Class<?> current = yourClass;
while(current.getSuperclass()!=null){ // we don't want to process Object.class
// do something with current's fields
current = current.getSuperclass();
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果你有权访问Spring Framework,有一个方便的方法来循环遍历类和所有超类的字段:(
另见我之前的答案:通过Java中的反射访问私有继承字段)
ReflectionUtils.doWithFields(baseClass, FieldCallback)
Ade*_*lin 11
这是我用来获取对象的所有字段的方法
private <T> List<Field> getFields(T t) {
List<Field> fields = new ArrayList<>();
Class clazz = t.getClass();
while (clazz != Object.class) {
fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
clazz = clazz.getSuperclass();
}
return fields;
}
Run Code Online (Sandbox Code Playgroud)
该解决方案使用 Java 8 流,对于那些正在学习 Java 函数式编程的人很有用。它按照其他答案迭代 getSuperclass 和 getDeclaredFields,但它以功能方式进行。
以下行将打印在 SomeClass 或其任何超类上找到的每个字段名称的名称。
allFieldsFor(SomeClass.class).map(Field::getName).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
下面是通过超类来创建字段流的代码。
private Stream<Field> allFieldsFor( Class c ) {
return walkInheritanceTreeFor(c).flatMap( k -> Arrays.stream(k.getDeclaredFields()) );
}
private Stream<Class> walkInheritanceTreeFor( Class c ) {
return iterate( c, k -> Optional.ofNullable(k.getSuperclass()) );
}
Run Code Online (Sandbox Code Playgroud)
以下方法是从 Streams.iterate 建模的,但是 Streams.iterate 旨在创建无限流。此版本已修改为在从 fetchNextFunction 返回 Optional.none() 时结束。
private <T> Stream<T> iterate( T seed, Function<T,Optional<T>> fetchNextFunction ) {
Objects.requireNonNull(fetchNextFunction);
Iterator<T> iterator = new Iterator<T>() {
private Optional<T> t = Optional.ofNullable(seed);
public boolean hasNext() {
return t.isPresent();
}
public T next() {
T v = t.get();
t = fetchNextFunction.apply(v);
return v;
}
};
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize( iterator, Spliterator.ORDERED | Spliterator.IMMUTABLE),
false
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
76640 次 |
| 最近记录: |