IDEA 插件告警描述 Raw use of parameterized class 'List'
问题分析及解决方案。
注意这只是告警,并不是错误,若不是强迫症或者代码要求非常严格,可以忽略。强迫症福音!
参考解决方案
CSDN-优秀参考博文
某天风和日丽,空气清新,虽然是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'
告警翻译:
参数化类“List”的原始使用
由于集合框架包含了许多Java开发者常用的数据结构,集合框架一般是通用的。因此我们在实际使用的时候通常会使用泛型来规范类型。但是呢,在泛型出现之前,List 等集合是没有类型规范的,因此我在生成这个List 重写方法的时候,没有添加泛型,就被工具插件判定为原始使用。
原始使用
在没有进行泛型指定类型或者进行类型通配时,一个集合是可以存放不同类型的数据的。这就导致了当要批量处理时,每次都要进行类型转换或开发者要严格根据每次存放的类型对应取出进行操作。这就容易出错且开发成本高。
当然,原始使用现在依然保留,是因为它依然具有灵活性,但实际开发中,现在一般只有特殊情况才原始使用。
说白了,就是没有添加泛型。
泛型
顺势来复习一下泛型吧。
表记符 | 含义 |
---|---|
E | Element,表示集合的元素 |
T | Type,表示类型。实际使用中,其实使用A、B等都可以,一般约定俗称用Type |
K | Key 键 |
V | Value 值 |
N | Number 数值类型 |
? | 通配符,表示不确定的类型 |
实际使用中,由于使用方便与约定俗成的关系,我们最常用的泛型标记符还是 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();
}
}
经过上述泛型的回顾,我们可以得知,出现该告警,直接添加泛型也是不行的,因此我们要先将类变成泛型类。下面介绍详细解决代码。
我个人练习所写的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;
}
}
接下来,可以愉快地实现这个类了!
以上问题出现在我个人的练习。实际工作中,需要注意通用工具类以及实现类的泛型指定!