Java 如何检查对象是否有字段

Java 如何检查对象是否有字段,java,arraylist,interface,Java,Arraylist,Interface,我有一个实现MarkerInterface的对象列表: 或 或 其中一些类有子类:Dog1扩展Dog,Dog2扩展Dog 有些类有parentId字段,而其他类没有 我想检查一个对象是否有parentId字段,如果它存在,则打印它的值 怎么做 我试过: list.get(i).getParentId(); 但它将不起作用,因为MarkerinInterface不能有getParentId方法,并不是所有实现MarkerinInterface的类都有parentId字段 如果父id字段不存在,您

我有一个实现MarkerInterface的对象列表:

其中一些类有子类:Dog1扩展Dog,Dog2扩展Dog

有些类有parentId字段,而其他类没有

我想检查一个对象是否有parentId字段,如果它存在,则打印它的值

怎么做

我试过:

list.get(i).getParentId();

但它将不起作用,因为MarkerinInterface不能有getParentId方法,并不是所有实现MarkerinInterface的类都有parentId字段

如果父id字段不存在,您希望打印什么

您可以通过查询对象来查看它是否有字段来实现这一点,例如,使用Java反射来检查对象的字段。或者,正如拉桑在评论中所建议的,您可以添加另一个接口并使用instanceof。但我鼓励您考虑其他方法,因为显式检查类的字段或询问其运行时类型通常是设计问题的迹象,以后可能会再次困扰您

另一种方法是向接口添加一个方法,该方法返回要打印的字符串。你可以有一个默认的实现,它返回或者你想打印的任何东西,而不是父id,这就是为什么我先问这个问题,然后在引入父id的基类中,你可以用一个返回父id的实现来覆盖

顺便说一句,它应该按照惯例拼写为parentId,但这对问题来说可能并不重要


然后,您可能希望组织类层次结构,以便所有具有parent_id的对象都可以获得它,以及通过公共父类返回它的重写实现;这对你的需要可能是可行的,也可能不是。如果没有,您可以使用更高级的模式来最小化代码重复,但对于问题的范围来说,这可能有点太深了。

如果父id字段不存在,您希望打印什么

您可以通过查询对象来查看它是否有字段来实现这一点,例如,使用Java反射来检查对象的字段。或者,正如拉桑在评论中所建议的,您可以添加另一个接口并使用instanceof。但我鼓励您考虑其他方法,因为显式检查类的字段或询问其运行时类型通常是设计问题的迹象,以后可能会再次困扰您

另一种方法是向接口添加一个方法,该方法返回要打印的字符串。你可以有一个默认的实现,它返回或者你想打印的任何东西,而不是父id,这就是为什么我先问这个问题,然后在引入父id的基类中,你可以用一个返回父id的实现来覆盖

顺便说一句,它应该按照惯例拼写为parentId,但这对问题来说可能并不重要


然后,您可能希望组织类层次结构,以便所有具有parent_id的对象都可以获得它,以及通过公共父类返回它的重写实现;这对你的需要可能是可行的,也可能不是。如果不是这样的话,可以使用更高级的模式来最小化代码重复,但是对于问题的范围来说,这可能有点钻得太深了。

正如您所建议的,我创建了ParentIdInterface,它扩展了MarkerinInterface并具有getParentId方法

if(list.get(i) instanceof ParentIdInterface) {
    ParentIdInterface pi = (ParentIdInterface) list.get(i);
    ...
}

现在它正是我想要的。谢谢。

正如您所建议的,我创建了ParentId接口,它扩展了MarkerinInterface并具有getParentId方法

if(list.get(i) instanceof ParentIdInterface) {
    ParentIdInterface pi = (ParentIdInterface) list.get(i);
    ...
}

现在它正是我想要的。谢谢。

如果您想使用Java反射,并且在类中有类似的内容:

public int parentId = 3;
您可以获得如下值:

    try {
        Field f = list.get(i).getClass().getField("parentId");
        int value = f.getInt(this);
        System.out.println("parentId="+value);
    } catch (NoSuchFieldException | SecurityException | IllegalArgumentException| IllegalAccessException e) {
        System.out.println("no Field named parentId");
    }

但是我建议使用其他人已经说过的接口。

如果您想使用Java反射,并且在类中有类似的内容:

public int parentId = 3;
您可以获得如下值:

    try {
        Field f = list.get(i).getClass().getField("parentId");
        int value = f.getInt(this);
        System.out.println("parentId="+value);
    } catch (NoSuchFieldException | SecurityException | IllegalArgumentException| IllegalAccessException e) {
        System.out.println("no Field named parentId");
    }

但我建议使用其他人已经说过的接口。

您需要另一个接口,如MarketWithParent Extendes MarketInterface,其中将定义getParent,然后您将能够使用instanceofJava反射@这是克拉克。从技术上讲,OP最好将getParent_id作为方法而不是字段进行检查。对于一个精心设计的课程来说,这个领域很有可能是私有的。你应该认真研究你正在创建的心智模型。当然,你可以使用更多的接口,甚至反射我的提示:不要去那里!。。。但是:在同一个列表中保留这么多不同的对象有什么意义@幽灵猫。我不确定你是否理解我。如果我有一个包含狗的文件,列表中的所有元素都是狗,如果文件包含人,我只将人添加到列表中。我不混合对象。您需要另一个接口,如MarketWithParent扩展MarketInterface,其中将定义getParent并
那么您就可以使用instanceofJava反射了吗@这是克拉克。从技术上讲,OP最好将getParent_id作为方法而不是字段进行检查。对于一个精心设计的课程来说,这个领域很有可能是私有的。你应该认真研究你正在创建的心智模型。当然,你可以使用更多的接口,甚至反射我的提示:不要去那里!。。。但是:在同一个列表中保留这么多不同的对象有什么意义@幽灵猫。我不确定你是否理解我。如果我有一个包含狗的文件,列表中的所有元素都是狗,如果文件包含人,我只将人添加到列表中。我不混合对象。然后:对于像id这样重要的东西,字符串是一个非常糟糕的选择。考虑一个特定的id类型,也就是类,可能会更好。这是真的;我没有看到任何标识id类型的东西,所以只是假设它将被转换为显示字符串用于打印目的…我将在一些操作中使用id,我现在跳过了这些操作。然后:对于像id这样重要的东西,字符串是一个非常糟糕的选择。可能最好也考虑一个特定的id类型aka类。这是真的;我没有看到任何标识id类型的内容,所以只是假设它将被转换为显示字符串以便打印…我将在一些操作中使用id,我现在跳过了这些操作。
    try {
        Field f = list.get(i).getClass().getField("parentId");
        int value = f.getInt(this);
        System.out.println("parentId="+value);
    } catch (NoSuchFieldException | SecurityException | IllegalArgumentException| IllegalAccessException e) {
        System.out.println("no Field named parentId");
    }