Generics и свой пример

116
02 июля 2019, 00:10

Просмотрел видео про Generic.

Класс GenericMain

public class GenericMain {
    public static void main(String[] args) {
        Container<Integer> box = new Container<>(2);
        Container<String> box2 = new Container<>("2");
    }
}

Класс Container

public class Container<T> {
   private T object1;
   public Container(T object1) {
      this.object1 = object1;
   }
   public T getObject1() {
      return object1;
   }
   public void setObject1(T object1) {
      this.object1 = object1;
   }
}

Вопрос 1. Почему мы параметризовали класс Container причем буквой . Я проверил и заменил <T> на <С>, так же отрабатывает. Cтранно, что автор умолчал.

Вопрос 2. Если заменить <T> на <Integer>, то есть сделать вот так:

public class Container<Integer> {
   private Integer object1;
   public Container(Integer object1) {
      this.object1 = object1;
   }
   public Integer getObject1() {
      return object1;
   }
   public void setObject1(Integer object1) {
      this.object1 = object1;
   }
}

То тоже ничего не происходит, я думал подсветит компилятор красным вот этот участок кода:

Container<String> box2 = new Container<>("2");

Потому что мы параметризовали класс Container как тип Integer, а в этом участке кода , но в итоге всё нормально, получается зачем мы тогда указываем тип классу(<>) Container? В моём случае я туда писал всё что можно и отрабатывало как я увидел всё нормально и ничего не подсвечивало.

Answer 1

Тут есть неправильное интерпретирование того, что написано в коде, нужно различать параметр типа (ориг. Type Parameter) и аргумент типа (ориг. Type Argument)

Тут задается тип передаваемый в качестве аргумента параметризации (в терминологии спецификации языка java - Type Argument):

new Continer<Integer>();

Тут декларирование параметра (в терминологии спецификации - Type Parameter):

class Container<Integer> { }

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

  • E - элемент (Element)
  • N - число (Number)
  • T - тип (Type)
  • К - ключ (Key)
  • V - значение (Value)

Все это можно найти в спецификации языка java https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html.

Если нужно что бы класс можно было параметризовать только числами и более специфичными типами, то нужно написать так:

class Container<T extends Number> {
    private T value
    public Container(T value) {
        this.value = value;
    }
    T getValue() { 
        return value; 
    }
}

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

class Container<String extends Number> {
        private String value;
        public Container(String value) {
            this.value = value;
        }
        String getValue() {
                return value;
        }
}

В данном случае String не будет интерпретироваться как тип java.lang.String, а как случайный набор символов задающий параметр.

Answer 2

Ошибок не происходит, т.к. вы создаете два разных объекта. У первого объекта у Container тип Integer, у второго - String.

У разных объектов одного класса могут быть разные типы в дженериках.

Если бы вы вообще не указали тип в <>, то как раз была бы ошибка, т.к. компилятор ждет указания типа класса Container.

Зачем вообще нужно это указывать - вы в первый объект не сможете "вставить" ничего кроме Integer, т.е. "2" или true например, а во второй - ничего кроме String.

READ ALSO
Отображение графика LineChart

Отображение графика LineChart

возникла такая проблемаМне нужно нарисовать график по Машине Тьюринга(зависимость кол-ва шагов от длины слова), когда я пытаюсь его нарисовать...

110
Анимация свайпа в вебвью

Анимация свайпа в вебвью

Хочу создать приложение-книжкуНа данный момент пришёл к решению использовать HorizontalWebView (нашёл на просторах stackoverflow)

135
Unicode и ASCII в Java

Unicode и ASCII в Java

Как известно, Java использует таблицу Unicode для кодировки символовНо при попытке привести символ к int, получается его значение этого символа...

143
Java Swing - как динамически изменять поля фрейма? [закрыт]

Java Swing - как динамически изменять поля фрейма? [закрыт]

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

121