android 如何在声明时禁止泛型的未检查类型转换警告?

gijlo24d  于 2023-04-04  发布在  Android
关注(0)|答案(3)|浏览(203)

我在下面的代码中使用ois.readObject()的List赋值抛出了一个未检查的类型转换警告。添加@SupressWarnings(“unchecked”)会让Android Studio给予我一个错误,说“此处不允许使用注解”。
是不是我唯一的选择来重新构造整个类,以便在那一行上声明Listtweets?

package com.fredliu.hellotwitter;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.fredliu.hellotwitter.models.Tweet;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

public class TweetListActivity extends BaseListActivityWithMenu {
    private List<Tweet> tweets;
    private static final String cacheFile = "tweetCache.ser";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tweet_list);
        try {
            FileInputStream fis = openFileInput(cacheFile);
            ObjectInputStream ois = new ObjectInputStream(fis);
            @SuppressWarnings(value="unchecked")
            tweets = (List<Tweet>) ois.readObject();

            ois.close();
            fis.close();
            Log.d("FREDFRED", "Tweets cache read from!");
        } catch (Exception e) {
            Log.e("FREDFRED", "Something horrible has happened when reading from the Tweets cache");
        }

        if (tweets == null || tweets.isEmpty()) {
            Toast.makeText(getApplicationContext(), "No stored Tweets found!", Toast.LENGTH_LONG).show();
            tweets = new ArrayList<>();
            for (int i = 1; i <= 20; i++) {
                Tweet t = new Tweet();
                t.setTitle("Title " + i);
                t.setBody("Body " + i);
                tweets.add(t);
            }
        }

        try {
            FileOutputStream fos = openFileOutput(cacheFile, MODE_PRIVATE);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(tweets);
            Log.d("FREDFRED", "Tweets successfully written to cache!");
        } catch (FileNotFoundException e) {
            Log.e("FREDFRED", "Tweet cache file not found" + e);
        } catch (IOException e) {
            Log.e("FREDFRED", "Object not found when writing Tweet to cache");
        }

        ArrayAdapter a = new TweetAdapter(this, tweets);
        setListAdapter(a);

    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Intent i = new Intent(this, TweetDetailActivity.class);
        startActivity(i);
        Toast.makeText(getApplicationContext(), "Position " + position + ", ID " + id, Toast.LENGTH_LONG).show();
    }
}
bybem2ql

bybem2ql1#

如果要取消显示单个语句的警告,只需插入以下内容:

// noinspection <checktype>

因此,对于您的情况,对于“未检查”,只需将其更改为:

// noinspection unchecked
tweets = (List<Tweet>) ois.readObject();

编辑:另一种方法是创建一些独立的方法来执行强制转换,然后将注解应用于该方法。类似于:

@SuppressWarnings("unchecked")
public static List<Tweet> asTweetList(ObjectInputStream ois) {
    return (List<Tweet>) ois.readObject();
}

然后用它来代替:

FileInputStream fis = openFileInput(cacheFile);
ObjectInputStream ois = new ObjectInputStream(fis);
List<Tweet> tweets = asTweetList(ois);

这使抑制范围保持紧密,并且不是特定于IDE的。

kq4fsx7k

kq4fsx7k2#

注解不能附加到表达式、语句或块上。因此,在这种情况下,您的选项是注解私有成员tweet,或者使用@SupressWarnings("unchecked")注解方法onCreate。如果您希望取消该类的所有未检查警告,您甚至可以注解整个类TweetListActivity(不推荐)。

h7wcgrx3

h7wcgrx33#

你可以添加@SuppressWarnings("unchecked") annotation,以抑制整个函数/方法的警告,比如:

@SuppressWarnings("unchecked")
MyResultType myFunction(MyInputType myValue)
{
    return (MyResultType) myValue;
}

或者在每一行添加一个inline-comment,比如:

//noinspection unchecked
tweets = (List<Tweet>) ois.readObject();

其中的区别在于内联注解是IDE的,至少我的Android编译器忽略了它并发出警告。
**然而,**说“suppress warnings from entire function”可能会隐藏一些其他问题,因此我更喜欢使用助手,如:

MyType myVariable = Unchecked.cast( myValue );

在OP的例子中:

tweets = Unchecked.cast( ois.readObject() );

需要将以下内容添加到项目中:

package my.package_name;

import androidx.annotation.NonNull;

/**
 * Helper similar to `@SuppressWarnings("unchecked")`, or `//noinspection unchecked` comment.
 *
 * <br><br><h2>The difference is that:</h2><ul>
 *
 * <li>Said annotation wraps entire function, causing more than needed to be ignored
 * (since it does not support placing inside of function, at time of writing).
 *
 * <li>The compiler may ignore said comment, and warn anyway.
 */
@SuppressWarnings("unchecked,unused,RedundantTypeArguments,RedundantSuppression")
public class Unchecked {
    /**
     * Type-cast implementation for reasons mentioned on {@link Unchecked} class.
     *
     * <br><br>Usage:
     * <pre>{@code
     * //noinspection RedundantTypeArguments
     * T myResult = Unchecked.<T>cast(myInput);
     * }</pre>
     *
     * <br><br>WARNING: To be sure compiler picks the right type,
     * set the type-argument, and suppress `RedundantTypeArguments`.
     */
    public static <NewType> NewType cast(@NonNull Object value) {
        return (NewType) value;
    }
}

相关问题