Java 扩展接口的泛型类型,除非我将其强制转换为特定类,否则我的变量将返回null
我有一个类,我正在使用一个泛型类型来扩展接口zwave 在出于某种原因尝试访问zwave变量之前,一切都很好。rm.keyword给出了NullPointerException。如果我把它投到课堂场景中,效果会很好,但这不是我想要的Java 扩展接口的泛型类型,除非我将其强制转换为特定类,否则我的变量将返回null,java,android,Java,Android,我有一个类,我正在使用一个泛型类型来扩展接口zwave 在出于某种原因尝试访问zwave变量之前,一切都很好。rm.keyword给出了NullPointerException。如果我把它投到课堂场景中,效果会很好,但这不是我想要的 public <T extends zwave> T Find(List<T> Zwave,List<List<String>> listofinputstrings) { for(List<String
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;
}
您需要使用getter方法。当您说rm.keyword时,这是指一个常量zwave.keyword,它是空字符串。当您强制转换到场景时,编译器会看到它是一个字段,并查找它
通常,除非您有特定的理由不使用getter和setter方法来操作它们,否则您应该将name和keyword等字段设置为private。接口中定义的变量是final static public,即使您没有显式定义。当变量为final时,一旦赋值,就不能再次赋值
因为您已经定义为空字符串,所以它将接受该值。但您需要在场景类中再次定义变量。因此,当您投射到场景时,对象将引用此变量,而不是界面中的变量。否则它将引用接口变量。如果不想强制转换,可以执行以下操作:
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;
}
注意:在场景类中定义getKeyword方法:
我可以在java.lang.reflect的帮助下对其进行更多的自定义。您甚至不需要使用场景实例。但我认为你自己可以做到。希望这会有所帮助。
使用反射API在运行时调用。rm.keyword为null或空字符串为?如何知道它为null?您是否收到NullPointerException?当您强制转换时和不强制转换时,实际会发生什么情况?如果您使用Java约定来启动类型名称(如带大写字母的ZWave),那么您的示例将更容易调试。请不要对实现类中的字段使用与接口中定义的常量相同的名称。这只是让每个看过代码的人都感到非常困惑。你所描述的问题是不可能的。强制转换不会神奇地将值从null更改为其他值。
public class Scene extends searchable
{
String name;
String zwaveID;
public Scene(String Name,String ZwaveID,String... Keywords)
{
name= Name;
zwaveID= ZwaveID;
keywords = Keywords;
}
}
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;