Когда не следует использовать дженерики Java

Spring Boot Java

1. Введение

Java 1.5Универсальные шаблоны введены для обеспечения безопасности типов, предотвращения исключений преобразования типов во время выполнения, параметризации типов и улучшения читаемости и повторного использования кода. Однако в некоторых случаях использование дженериков не допускается.Сегодня мы обобщим некоторые сценарии, в которых нельзя использовать дженерики в кодировании.

2. Базовые типы не могут напрямую использовать дженерики

Следующее написание неверно:

// error 
Map<int,char> wrong= new HashMap<>()

Базовые типы нельзя использовать в качестве универсальных типов, вам необходимо использовать соответствующие им классы-оболочки.

// OK
Map<Integer,Character> wrong= new HashMap<>()

3. Общие типы не могут быть созданы напрямую

Общий тип можно понимать как абстрактный тип, который просто представляет собой абстракцию типа, поэтому мы не можем напрямую создавать его экземпляры.Следующий подход также неверен:

 public <E> E first(List<E> list){
     // error 
        E e = new E();
       return list.get(0);   
 }

4. универсальный тип не может быть статической переменной

JavaСтатический тип в классе создается при загрузке класса, а конкретный тип универсального типа в это время не объявляется. В то же время, поскольку статические переменные являются общими переменными всех объектов, их типы можно определить только при создании экземпляра класса или вызове метода. Если это универсальный тип, его тип не может быть определен. Универсальный тип, объявленный в классе, также не может появляться в статическом методе класса в качестве типа возвращаемого значения.Следующее написание также неверно:

public class Generic<T>{
    // 不能将类声明的泛型类型作为静态变量
    public static T t;
    // 也不能将类声明的泛型类型作为 静态方法的返回值
    public  static  T  rtval(List<T> list){
        return list.get(0);
    }
}

5. Не может выносить приговор

JavaУниверсальный тип является псевдоуниверсальным типом, который будет стерт во время компиляции.В работающем байт-коде нет универсального типа, поэтому следующие условия оценки не могут быть выполнены:

public static <E> void wrong(List<E> list) {
    // error 
    if (list instanceof ArrayList<Integer>) {   
    }
}

Но общие неограниченные подстановочные знаки<?>можно продолжитьinstanceofСудья, ты подумай, почему.

6. Невозможно создать массив параметризованного типа

Прежде всего верно следующее:

// OK
List[] arrayOfLists = new List[2];

Но с добавлением дженериков компиляция не работает:

//error
List<Integer>[] arrayOfLists = new List<Integer>[2];

Если этого не сделать, возникнут следующие логические ошибки:

// 如果上面的成立,则下面的也应该成立
Object[] stringLists = new List<String>[];  
// 那么我们可以放入 字符串 List
stringLists[0] = new ArrayList<String>();   
// 放入 Integer list
stringLists[1] = new ArrayList<Integer>();
// 这显然不合理

7. Throwable не может быть расширен прямо или косвенно

Следующие два способа записи вызовут ошибки компиляции:

//  不能间接地扩展 Throwable   
class IndirectException<T> extends Exception {}     

//  不能直接地扩展 Throwable  
class DirectException<T> extends Throwable {} 

Если он появится, если он установлен:

 try {
        // ...
    } catch (T e) {   
        // 类型不确定  无法处理具体的异常逻辑
    }

Как можно конкретно обрабатывать исключения, что явно не удобно для точной логики обработки исключений. Но вы можете сгенерировать неопределенное исключение, но вы не можете использовать дженерики, объявленные в классе, в статических методах:

class Parser<T extends Exception> {
   // 这样是对的
    public void okThrow(File file) throws T {      
        // ...
    }
    // 静态方法不能出现类声明的泛型类型作为返回值和异常
    public static void wrongThrow(File file) throws T {      
    }
}

8. Методы с одной и той же сигнатурой параметра не могут быть перегружены после универсального стирания.

Из-за универсального стирания следующие методы не считаются перегрузками методов и не будут компилироваться:

public class NoReload {
    public void sets(Set<String> strSet) { }
    public void sets(Set<Integer> intSet) { }
}

9. Резюме

подведены итоги сегодняJavaНекоторые недоразумения в использовании дженериков, хотя обычные подсказки IDE скажут нам, но это также некоторые точки знаний, которые мы часто игнорируем. Если есть какие-либо недостатки, пожалуйста, оставьте сообщение для исправления. Если вы хотите узнать больше о Generics, вы можете следить за официальной учетной записью:Код Фермер Маленький Толстый БратОтветитьgenericПолучите соответствующие учебные заметки.

关注公众号:Felordcn获取更多资讯

Личный блог: https://felord.cn