【杂谈】Raw use of parameterized class ‘List‘ 解决方案

Raw use of parameterized class 'List' 解决方案

0. 前言

IDEA 插件告警描述 Raw use of parameterized class 'List' 问题分析及解决方案。

注意这只是告警,并不是错误,若不是强迫症或者代码要求非常严格,可以忽略。强迫症福音!

参考解决方案
CSDN-优秀参考博文

1. 问题描述

某天风和日丽,空气清新,虽然是996,但同事请假了,某些要通力合作的业务只能放缓,工作任务暂时空缺,是自己写点东西的好时机。

于是,我兴致勃勃地打开了尘封已久的《数据结构》,并照着教程打算自己用Java写一个线性表。

我们知道,Java实现数据结构有个小优势,ADT可以用接口取代,因此我写了如下接口:

public interface ILinearList<T> {
    /**
     * if it is empty
     * @return if it is empty return true, else return false
     */
    boolean isEmpty();

    /**
     * return this list's length
     * @return length
     */
    int size();

    /**
     * get the element from index i
     * @param i index
     * @return element in index i
     */
    T get(int i);

    /**
     * set x into index i
     * @param i index
     * @param x element
     * @return if it is success
     */
    boolean set(int i, T x);

    /**
     * toString
     * @return string value
     */
    @Override
    String toString();

    /**
     * insert x into index i
     * @param i index
     * @param x element x
     * @return index
     */
    int insert(int i, T x);

    /**
     * insert x into the tail of the list
     * @param x element x
     * @return index
     */
    int insert(T x);

    /**
     * remove elements in index i
     * @param i index i
     * @return element in index i
     */
    T remove(int i);

    /**
     * search element equals key
     * @param key key
     * @return index
     */
    int search(T key);

    /**
     * if this
     * @param key key element
     * @return if it contains this element
     */
    boolean contains(T key);

    /**
     * insert different element
     * @param x target element
     * @return if contains that element, return -1, else return index
     */
    int insertDifferent(T x);

    /**
     * remove target key
     * @param key target
     * @return target key
     */
    T remove(T key);

    /**
     * equals another liner list
     * @param obj liner list
     * @return if it is equals
     */
    @Override
    boolean equals(Object obj);

    /**
     * override hash code
     * @return hash code
     */
    @Override
    int hashCode();

    /**
     * add another liner list
     * @param list target list
     * @return if it is success
     */
    boolean addAll(List<T> list);
}

使用接口定义了ADT的操作之后,就是要写实现类了,实现类一开始的时候如下:

public class SequenceTable implements ISequenceTable {


    @Override
    public boolean isEmpty() {
        return false;
    }

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

    @Override
    public Object get(int i) {
        return null;
    }

    @Override
    public boolean set(int i, Object x) {
        return false;
    }

    @Override
    public int insert(int i, Object x) {
        return 0;
    }

    @Override
    public int insert(Object x) {
        return 0;
    }

    @Override
    public Object remove(int i) {
        return null;
    }

    @Override
    public int search(Object key) {
        return 0;
    }

    @Override
    public boolean contains(Object key) {
        return false;
    }

    @Override
    public int insertDifferent(Object x) {
        return 0;
    }

    @Override
    public Object remove(Object key) {
        return null;
    }

    @Override
    public boolean addAll(List list) {
        return false;
    }
}

在具体方法还没写的时候,IDEA报如下告警:
Raw use of parameterized class 'List'
1

2. 问题分析

告警翻译:
参数化类“List”的原始使用

由于集合框架包含了许多Java开发者常用的数据结构,集合框架一般是通用的。因此我们在实际使用的时候通常会使用泛型来规范类型。但是呢,在泛型出现之前,List 等集合是没有类型规范的,因此我在生成这个List 重写方法的时候,没有添加泛型,就被工具插件判定为原始使用。

原始使用
在没有进行泛型指定类型或者进行类型通配时,一个集合是可以存放不同类型的数据的。这就导致了当要批量处理时,每次都要进行类型转换或开发者要严格根据每次存放的类型对应取出进行操作。这就容易出错且开发成本高。
当然,原始使用现在依然保留,是因为它依然具有灵活性,但实际开发中,现在一般只有特殊情况才原始使用。

说白了,就是没有添加泛型。

泛型
顺势来复习一下泛型吧。

  • 泛型标记符
表记符含义
EElement,表示集合的元素
TType,表示类型。实际使用中,其实使用A、B等都可以,一般约定俗称用Type
KKey 键
VValue 值
NNumber 数值类型
通配符,表示不确定的类型

实际使用中,由于使用方便与约定俗成的关系,我们最常用的泛型标记符还是 T?

  • 泛型接口

    • 语法
      在接口名后添加泛型:
interface GenericsInterface<T> {
	T method(T t);
	// other methods ...
}
    • 作用
      如果一个接口使用了泛型,那么实现该接口的类可以就可以指定类型,举个例子:
interface GenericsInterface<T> {
	/**
	 * 泛型接口演示
	 * @param t 泛型对象t
	 * @return 返回泛型对象
	 */
	T method(T t);
}
public class Cat extends Animal implements GenericsInterface<Cat> {
    private String color;

    public void voice(){
        System.out.println("mao mao");
    }

    @Override
    public Cat method(Cat cat) {
        return null;
    }
}

当我们实现泛型接口,而不指定泛型时,默认为Object:

public class Cat extends Animal implements GenericsInterface {
    private String color;

    public void voice(){
        System.out.println("mao mao");
    }

    @Override
    public Object method(Object o) {
        return null;
    }
}

  • 泛型类

    • 语法
      在类名后添加泛型:
class GenericsClass<T> {
	T method(T t);
	// other methods ...
}

当我们实例化这个泛型类的对象时,就可以指定泛型了。

    • 举例
public class MyStack <T> {

    LinkedList<T> values = new LinkedList<>();

    public void push(T t){
        values.addLast(t);
    }

    public T pull(){
        return values.removeLast();
    }

    public T peek(){
        return values.getLast();
    }

    public static void main(String[] args) {
        MyStack<Car> carStack = new MyStack<>();
        carStack.push(new Car());
        carStack.push(new Car());
        carStack.peek();
        Car pull = carStack.pull();

        MyStack<Cat> catMyStack = new MyStack<>();
        catMyStack.push(new Cat());
        catMyStack.push(new Cat());
        catMyStack.push(new Cat());
        Cat cat = catMyStack.pull();
    }
}

经过上述泛型的回顾,我们可以得知,出现该告警,直接添加泛型也是不行的,因此我们要先将类变成泛型类。下面介绍详细解决代码。

3. 问题解决

我个人练习所写的ADT是使用了泛型通配符,因此实际解决时,我们也将实现类添加上通配符,告警消失,代码如下:

public class SequenceTable<T> implements ISequenceTable<T> {

    @Override
    public boolean isEmpty() {
        return false;
    }

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

    @Override
    public T get(int i) {
        return null;
    }

    @Override
    public boolean set(int i, T x) {
        return false;
    }

    @Override
    public int insert(int i, T x) {
        return 0;
    }

    @Override
    public int insert(T x) {
        return 0;
    }

    @Override
    public T remove(int i) {
        return null;
    }

    @Override
    public int search(T key) {
        return 0;
    }

    @Override
    public boolean contains(T key) {
        return false;
    }

    @Override
    public int insertDifferent(T x) {
        return 0;
    }

    @Override
    public T remove(T key) {
        return null;
    }

    @Override
    public boolean addAll(List<T> list) {
        return false;
    }
}

接下来,可以愉快地实现这个类了!

4. 总结

以上问题出现在我个人的练习。实际工作中,需要注意通用工具类以及实现类的泛型指定!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值