Java 如何通过反射得到字段的packagename?

Java 如何通过反射得到字段的packagename?,java,reflection,Java,Reflection,我想检测类中的字段,这些字段要么是像Address这样的自定义字段,要么是本机java字段 因此,我试图读取每个字段的包名,以便稍后检查它们是否以java.*开头 问题:显示的包始终是java.lang。为什么?java.lang是在任何java类上隐式导入的包。这就是为什么您可以引用其中包含的许多类,如对象或字符串,而不必在源代码中包含任何导入 但是,没有任何东西可以阻止您或任何人创建名为java.lang的包并在其中包含您自己的类。因此,无论您认为这是什么,这都不是区分本机Java与自定义字

我想检测类中的字段,这些字段要么是像Address这样的自定义字段,要么是本机java字段

因此,我试图读取每个字段的包名,以便稍后检查它们是否以java.*开头

问题:显示的包始终是java.lang。为什么?

java.lang是在任何java类上隐式导入的包。这就是为什么您可以引用其中包含的许多类,如对象或字符串,而不必在源代码中包含任何导入

但是,没有任何东西可以阻止您或任何人创建名为java.lang的包并在其中包含您自己的类。因此,无论您认为这是什么,这都不是区分本机Java与自定义字段的实用方法

我认为您还应该找出加载您正在测试的每个特定类的类加载器。

您必须调用getType而不是getGenericType。考虑这个例子:

public class Sandbox {

    public int intField;
    public Sandbox myField;

    public static void main(String[] args) {
        Arrays.stream(Sandbox.class.getDeclaredFields()).forEach(f ->
                System.out.println(f.getName() + " : " + f.getType().getName()));

    }
}
输出


好的,您要求它提供MyDTO.class,因此它返回一个class对象,它位于java.lang中。您可以查询泛型类型:field.getGenericType。。。。我认为您实际上想要的是field.getType…您喜欢getName还是getCanonialName?不幸的是,对于私有布尔布尔字段;这不会打印java.lang.boolean,而只是“boolean”。因此,这对检测自定义对象不起作用。@membersound规范名称在这里会更好,但全名方法确实不太好,您已经指出了一些原因。自定义类型的标准是什么?对于基元类型,Field.getPackage为null。我们必须首先定义筛选条件。好的,然后我可以排除任何包为null的字段,并检查其他字段的包名。“没有任何东西阻止您或任何人创建名为java.lang的包”-除非像类装入器这样的正式规则会拒绝任何加载名称以java开头的类的尝试。从用户类路径。
public class Sandbox {

    public int intField;
    public Sandbox myField;

    public static void main(String[] args) {
        Arrays.stream(Sandbox.class.getDeclaredFields()).forEach(f ->
                System.out.println(f.getName() + " : " + f.getType().getName()));

    }
}
intField : int
myField : my.answer.Sandbox