无法将ArrayList<String>转换为ArrayList<java.lang.String>。

4

我有一个奇怪(在我看来)的问题。我目前正在制作一个自定义的JComboBoxModel,以满足我从一些自定义渲染器中需要的自定义功能,但我还不确定如何处理它,稍后我会发布相关内容。

无论如何,正如标题所示,我遇到了一些类型错误。

这是该类(当前)的代码:

package miscclasses;
import java.util.ArrayList;
import javax.swing.AbstractListModel;

public class CustomComboBoxModel<String> extends AbstractListModel<String> {
    /**
     * Contains a list of row indexes that shouldn't be displayed.
     */
    private ArrayList<String> alreadySelectedIndexes;
    /**
     * The comboBoxes selected index.
     */
    private int selectedIndex=-1;
    /**
     * Contains a list of values in this model.
     */
    private ArrayList<String> vals;
    /**
     * Creates an empty CustomComboBoxModel.
     */
    public CustomComboBoxModel() {
        this.alreadySelectedIndexes=new ArrayList<>();
        this.vals = new ArrayList<>();
    }
    /**Creates a CustomComboBoxModel with the values passed in.
     * 
     * @param values the row values.
     */
    public CustomComboBoxModel(ArrayList<String> values) {
        this();
        this.vals.addAll(values);
    }

    public CustomComboBoxModel(ArrayList<String> values, ArrayList<String> alreadySelected) {
        this(values);
        this.alreadySelectedIndexes.addAll(alreadySelected);
    }

    public CustomComboBoxModel(ArrayList<String> values, ArrayList<String> alreadySelected, int selectedIndex) {
        this(values, alreadySelected);
        this.selectedIndex=selectedIndex;
    }

    public CustomComboBoxModel(ArrayList<String> values, ArrayList<String> alreadySelected, String selectedValue) {
        this(values, alreadySelected);
        if(!this.vals.isEmpty()) {
            //this.selectedIndex = Misc.containsI(this.vals, selectedValue);
        }
    }

    @Override
    public int getSize() {
        return this.vals.size();
    }

    @Override
    public String getElementAt(int i) {
        return this.vals.get(i);
    }

    public boolean isRowSelected(int i) {
        return ((!this.alreadySelectedIndexes.contains(Integer.toString(i)))?false:true);
    }
}

我收到的错误在第55行,那里我试图获取所选值的索引。这是在接受两个ArrayList列表和一个String值的构造函数中被注释的行。错误显示“没有适合的方法用于containsI(java.util.ArrayList,String)方法miscclasses.Misc.containsI(java.util.ArrayList,java.lang.String)不适用”。据我所知,String和java.lang.String是完全相同的。因此,我无法弄清楚可能会导致这个问题,想请教那些对Code-fu更有了解的人。供参考,Misc.containsI(ArrayList,String)代码在此处:
 /**
 * Finds the index of value Target. Returns -1 if this ArrayList doesn't contain Target.
 * @param a         ArrayList of Strings a.
 * @param target    Value to find.
 * @return          Index of target if found; Else returns -1.
 */
public static int containsI(ArrayList<String> a, String target) {
    for (int i = 0; i < a.size(); i++)
    {
        if(a.get(i).equalsIgnoreCase(target))
            return i;
    }
    return -1;
}

我在isRowSelected(int i)函数中奇怪地收到以下警告:

"Suspcious call to java.util.Collection.contains: Expected type String, actual type String"。

再次强调,我不明白为什么会出现这样的警告。这似乎是完全有效的代码,而且我以前也做过类似的事情。如果能帮忙解决这个奇怪的警告和错误,我将不胜感激。

编辑:更改声明以便读取:

public class CustomComboBoxModel extends AbstractListModel<String>

替代:

public class CustomComboBoxModel<String> extends AbstractListModel<String>

看起来已经消除了警告和错误。然而,我不理解为什么会这样,因为我有一个声明为Custom JList mode的自定义JList模式:

public class CustomListModel<String> extends javax.swing.DefaultListModel<String>

在同一个包中没有错误。
1个回答

11

在这一行中,您声明了一个名为String的类型参数:

public class CustomComboBoxModel<String> extends AbstractListModel<String> {
                                 ^^^^^^

当您稍后引用 String 时,编译器会认为您指的是类型参数,而不是 java.lang.String 类。

这里的解决方法是删除类型参数,因为您不需要类型参数。


以下简化示例会给出类似的错误消息:

class Foo<String>
{
    String s = ""; // error: incompatible types
}

完整的错误信息如下:

Main.java:3: 不兼容的类型
找到:java.lang.String
需要:String
    String s = "";
               ^

在线查看:ideone


提到这一点是有道理的,考虑到错误和警告的措辞。但奇怪的是,我没有这样的类,然而,在此包中的其他类中尝试会导致相同的错误。 不过,出于某种原因,将类声明从“public class CustomComboBoxModel<String> extends AbstractListModel<String>”更改为“public class CustomComboBoxModel extends AbstractListModel<String>”就解决了问题。 我不太明白为什么会这样,但感谢您的帮助,否则我永远不会尝试那样做。编辑:您知道为什么更改后问题消失了吗? - Legowaffles
@Legowaffles:啊,我现在明白了。你将String创建为类的类型参数。你至少应该得到一半的功劳来解决这个问题! - Mark Byers
除了一个扩展默认模型之外,这个和我上面提到的JList模型有什么区别?我不太理解它们之间的区别。请参阅我在主帖中的编辑以获取更多详细信息。 - Legowaffles
@Legowaffles:这个语法本身并不是错误的——完全可以有一个类型参数叫做String,在某些情况下它甚至可能编译并且运行没有问题。问题在于如果你在类内部有类似String s = "";这样的代码,那么你将会得到一个类型错误,因为字面字符串具有实际的java.lang.String类型,而不能分配给你的String类型。 - Mark Byers
嗯,如果我的理解没错的话,在我的自定义JList模型类中,从CustomListModel<String>中移除<String>可能是明智之举,以防未来可能发生的问题。编辑:果然,尝试在我的自定义JList模型中做类似的操作导致了相同的错误。非常感谢您的帮助。 - Legowaffles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接