Какова концепция CAP # 1 в универсальной (подстановочный знак) JAVA?

java generics parameter-passing wildcard

1794 просмотра

2 ответа

544 Репутация автора

Рассмотрим следующий пример:

class First<T >
{
  T s;
  First(T s)
  {
        this.s=s;
  }
  void setS(T s)
  {
        this.s=s;
  }
  void getS()
  {
    System.out.println(s);
  }
}

class Use
{
        public static void setFirst(First<?>f)
        {
                f.setS(7);
        }
        public static void main(String[] args)
        {
                First <Integer> f4 = new First<Integer>(5);
                f4.getS(); 
                setFirst(f4);                   
        }
}

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

gyan@ns:~/codes/java/generics$ javac -Xdiags:verbose *.java
Use.java:5: error: method setS in class First<T> cannot be applied to given types;
        f.setS(7);
         ^
  required: CAP#1
  found: int
  reason: argument mismatch; int cannot be converted to CAP#1
  where T is a type-variable:
    T extends Object declared in class First
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ?
1 error
gyan@ns:~/codes/java/generics$ 

Похоже, что CAP # 1 является типом данных. Я ничего не знаю об этой концепции. Пожалуйста помоги.

Автор: my name is GYAN Источник Размещён: 19.07.2016 04:04

Ответы (2)


0 плюса

4009 Репутация автора

В дженериках все заменяется только во время компиляции для обеспечения безопасности типа.

В вашем примере компилятор обрабатывает fвходной параметр как имеющий тип Object. Когда setFirst(First<?>f)метод вызывает, f.setS(7);компилятор не может подтвердить тип объекта, в который инициализируется, и возникает ошибка.

Когда возникает этот тип ошибки, это обычно означает, что компилятор считает, что вы назначаете неправильный тип переменной. Дженерики были добавлены в язык Java для обеспечения безопасности типов во время компиляции.

public static void setFirst(First<?>f) // at compile time no special type parameter found. So No Replacement will take place.
        {
                f.setS(7); //confusing case because it not a type Parameter should be replace with any Java Class not the Constant.
        }

Но вот в других случаях в основном

First <Integer> f4 = new First<Integer>(5); // T is replaced with Integer.
 f4.getS(); // It will produce 5
 setFirst(f4);  // it will also get executed because of f4 is a object of First<Integer>.
Автор: Vikrant Kashyap Размещён: 19.07.2016 04:39

0 плюса

18588 Репутация автора

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

Однако вы можете изменить тип параметра на <Integer>или <? super Integer>заставить этот метод работать:

public static void setFirst(First<Integer> f) {
    f.setS(7);
}

Ссылка: подстановочные знаки в дженериках

Автор: sactiw Размещён: 30.10.2017 07:04
Вопросы из категории :
32x32