-4

我有一个类,我使用扩展接口 zwave 的通用类型,一切都很好,直到我尝试访问 zwave 变量,由于某种原因 rm.keyword 给出了“NullPointerException”。如果我将它投射到课堂场景中它会起作用,但这不是我想要的

public <T extends zwave> T Find(List<T> Zwave,List<List<String>> listofinputstrings)
{
    for(List<String> lst: listofinputstrings)
    {
        for(String str: lst)
        {

            for (T rm: Zwave)
            {
    //*** problem is here
    //rm.keyword is always gives a NullPointerException unless i cast it to a class
               if (rm.keyword.equals( str.toLowerCase()))
               {
                   return  rm;
               }
            }

        }
    }


    return  null;
}

//这里是接口

 interface zwave
 {
    public String keyword="";
    public String zwaveID="";
 }

//这里是一个实现接口的类

public class Scene implements zwave
{
   String name;
   String keyword;
   String zwaveID;

    public Scene(String Name,String Keyword,String ZwaveID)
    {
        name= Name;
        zwaveID= ZwaveID;
        keyword = Keyword;
    }
}

编辑

工作代码

//搜索类

public <T extends searchable> T Find(List<T> searchableclasses, List<List<String>> listofinputstrings)
{
    for(List<String> lst: listofinputstrings)
    {
        for(String str: lst)
        {

            for (T searchable: searchableclasses)
            {

                for(String key: searchable.GetKeywords())
                {
                    if ( key.equals(str.toLowerCase()))
                    {
                        return searchable;
                    }
                }
            }

        }
    }


    return  null;
}

//抽象类

 abstract class searchable
 {
    String[]  keywords; //using array so i can use java's param ability
    public List<String> GetKeywords()
    {
        return new ArrayList(Arrays.asList(keywords));
    }
 }

//实际类

public class Scene extends searchable
{
   String name;
   String zwaveID;

    public Scene(String Name,String ZwaveID,String... Keywords)
    {
        name= Name;
        zwaveID= ZwaveID;
        keywords = Keywords;
    }
}
4

3 回答 3

1

您需要使用 getter 方法。当您说rm.keyword时,它指的是一个常量 ( zwave.keyword),它是空字符串。当您转换为Scene时,编译器会看到它是一个字段并改为查找它。

通常,您应该将字段设置为nameand ,keyword private除非您有特定的理由不这样做,并使用 getter 和 setter 方法来操作它们。

于 2013-08-25T04:50:27.313 回答
1

如果你不想投,你可以做这样的事情:

public <T extends zwave> T Find(List<T> Zwave,List<List<String>> listofinputstrings)
{

for(List<String> lst: listofinputstrings)
{
    for(String str: lst)
    {
        for (T rm: Zwave)
        {
    if(rm instanceof Scene){
        Method method=null;
        try {
             method = rm.getClass().getMethod("getKeyword");
                           if ( method.invoke(rm).equals( str.toLowerCase()))
                           {
                                  return  rm;
                            }
            } catch (Exception e) {
             e.printStackTrace();
            } 

    }


        }

    }
}


return  null;

}

注意:在 Scene 类中定义 getKeyword 方法:
我可以借助 java.lang.reflect 对其进行更多自定义。你甚至不需要使用 Scene 的实例。但我认为你可以自己做。并希望它会有所帮助。使用反射 API在运行时调用。

于 2013-08-25T05:35:54.450 回答
0

即使您没有明确定义,接口中定义的变量也是最终的静态公共变量。当变量是最终变量时,一旦分配了值,您就不能再次重新分配它。

由于您已将其定义为空字符串 (""),它将采用该值。Scene但是您在类中再次定义变量。因此,当您转换为 Scene 对象时,将引用此变量而不是界面中的变量。否则它指的是接口变量。

于 2013-08-25T05:19:36.687 回答