将未经检查的 java.io.Serializable 强制转换为 java.util.ArrayList

18

请帮忙,我在以下代码中收到以下消息:

listaFinal = (ArrayList<PuntoNota>) getIntent().getSerializableExtra("miLista");

AdapterDatos adapter = new AdapterDatos(this, listaFinal);

PuntoNota.java

public class PuntoNota implements Serializable{
private String punto;
private String nota;

public PuntoNota (String punto, String nota){
    this.punto = punto;
    this.nota = nota;
}

public String getPunto(){
    return punto;
}


public String getNota(){
    return nota;
}

}

AdapterDatos:

public AdapterDatos(Context context, ArrayList<PuntoNota> puntoNotaList) {
    this.context = context;
    this.puntoNotaList = puntoNotaList;
}

应用程序运行良好,但我收到以下消息:

未经检查的强制转换:将 'java.io.Serializable' 转换为 'java.util.ArrayList' less ... (Ctrl + F1)。
关于此代码:(ArrayList ) getIntent().getSerializableExtra("myList"); 是否建议删除或隐藏此消息?


这只是一个警告信息。 - Mạnh Quyết Nguyễn
@MạnhQuyếtNguyễn,但解决从可序列化到相应所需的泛型列表的转换将有助于良好的编程实践。否则,当您使用Parcelable时,数据类型在两端预先知道,这个问题就得到了解决。 - Abhinav Saxena
它只是用于警告使用情况,而不是编译代码检查。你的解决方案只是隐藏了它,也没有解决它。所以除非改为类型安全的可序列化,否则就接受它吧。 - Mạnh Quyết Nguyễn
2个回答

16

根本原因:这是来自IDE的警告,getSerializableExtra返回一个Serializable对象,而您正在尝试转换为ArrayList<PuntoNota>。如果程序无法将其强制转换为预期类型,则可能在运行时抛出ClassCastException

解决方案:在Android中传递用户定义的对象时,您的类应该实现Parcelable接口,而不是Serializable接口。

class PuntoNota implements Parcelable {
    private String punto;
    private String nota;

    public PuntoNota(String punto, String nota) {
        this.punto = punto;
        this.nota = nota;
    }

    protected PuntoNota(Parcel in) {
        punto = in.readString();
        nota = in.readString();
    }

    public String getPunto() {
        return punto;
    }

    public String getNota() {
        return nota;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(punto);
        dest.writeString(nota);
    }

    public static final Creator<PuntoNota> CREATOR = new Creator<PuntoNota>() {
        @Override
        public PuntoNota createFromParcel(Parcel in) {
            return new PuntoNota(in);
        }

        @Override
        public PuntoNota[] newArray(int size) {
            return new PuntoNota[size];
        }
    };
}

在发件人侧

ArrayList<PuntoNota> myList = new ArrayList<>();
// Fill data to myList here
...
Intent intent = new Intent();
intent.putParcelableArrayListExtra("miLista", myList);

在接收端

ArrayList<? extends PuntoNota> listaFinal = getIntent().getParcelableArrayListExtra("miLista");

11

您可以使用警告抑制注释@SuppressWarnings来设置警告抑制。

例如:

You can set a warning Suppression @SuppressWarnings annotation.

翻译后为:

您可以使用警告抑制注释@SuppressWarnings来设置警告抑制。

@SuppressWarnings("unchecked")
listaFinal = (ArrayList<PuntoNota>) getIntent().getSerializableExtra("miLista");

这是一个注解,用于抑制编译警告,针对未检查的泛型操作(非异常),例如强制类型转换。这实际上意味着程序员不希望在编译特定代码时被通知这些警告,因为他们已经知道这些警告。

您可以在此处阅读有关此特定注解的更多信息:

SuppressWarnings

此外,Oracle在此提供了一些关于注解使用的教程文档:

Annotations

正如他们所说,

“'unchecked'警告可能在与早期的泛型代码(在标题为Generics的课程中讨论)进行接口时发生。”


7
这个技巧让我的眼睛现在感到放松,谢谢。 另外,你应该在你的方法上面加上@SuppressWarnings("unchecked") - AlexS
1
你也可以将它放在类声明的上方。这将消除与此相关的所有警告。 - Abhinav Saxena

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