2016-06-06 3 views
-1

Мой предыдущий SSCCE был некорректен сам. Я попытался написать еще один, но он тоже был неправильным. Итак, сейчас я не понимаю эту проблему и, следовательно, не может писать чистый пример Java и поэтому я проводки пример с классами библиотеки:Попытка №3: ​​Невозможно сформировать выражение требуемого типа с двумя вопросительными знаками в Java

import javafx.scene.control.TableCell; 
import javafx.scene.control.TableColumn; 
import javafx.util.Callback; 

public class DoubleQuestionMark3 { 

    public static class MyClass { 
    } 

    public static void main(String[] args) { 

     TableColumn<MyClass, ?> column = new TableColumn(); 

     Callback<TableColumn<MyClass, ?>, TableCell<MyClass, ?>> callback = new Callback<TableColumn<MyClass, ?>, TableCell<MyClass, ?>>() { 
     @Override 
     public TableCell<MyClass, ?> call(TableColumn<MyClass, ?> param) { 
      return null; 
     } 
     }; 

     column.setCellFactory(callback); 

    } 
} 

Вопрос заключается в том же: как приготовить callback соответствующего класса?

Если невозможно, то, во-первых, пожалуйста, укажите, что это действительно невозможно, и, во-вторых, объясните, почему это невозможно.

UPDATE

Указание Object для обратного вызова не помогает:

Callback<TableColumn<MyClass, Object>, TableCell<MyClass, Object>> callback = new Callback<TableColumn<MyClass, Object>, TableCell<MyClass, Object>>() { 
     @Override 
     public TableCell<MyClass, Object> call(TableColumn<MyClass, Object> param) { 
      return null; 
     } 
     }; 
+0

Почему вы просто не редактируете существующие вопросы, которые вы написали для этого ...? – Makoto

+0

Потому что я получил буквально правильный ответ от новичка. – Dims

+3

Проблема - это подстановочный знак '?'. Почему вы его используете? 'setCellFactory' требует' Callback , TableCell > 'как параметр, то есть те же' S' и 'T'. Подстановочный знак не выполняет этого, он говорит, что это может быть какой-то «тип». – Tunaki

ответ

1

Когда вы объявляете переменную с типом TableColumn<MyClass, ?>, то ? обозначает неизвестный тип, так что невозможно для определения соответствующей типизированной переменной Callback, поскольку она относится к неизвестному типу.

Если у вас есть общий код, который может иметь дело с произвольным типом, вы должны записать этот код в классе или методе с переменной типа, указав неизвестный тип имени, например, вы можете использовать ссылку на метод:

public class DoubleQuestionMark3 { 

    public static void main(String[] args) { 
     TableColumn<MyClass, ?> column = new TableColumn(); 
     column.setCellFactory(DoubleQuestionMark3::call); 
    } 
    static <T> TableCell<MyClass, T> call(TableColumn<MyClass, T> param) { 
     // fill with life... 
     return new TableCell<>(); 
    } 
} 

Это работает, как код, работающий с произвольным типом T, могут быть использованы, даже если вызывающий абонент не знает тип, как с TableColumn<MyClass, ?>.


В качестве альтернативы, вы можете переместить весь код инициализации в общий метод:

public class DoubleQuestionMark3 { 

    public static void main(String[] args) { 
     TableColumn<MyClass, ?> column = new TableColumn(); 
     initialize(column); 
    } 
    static <T> void initialize(TableColumn<MyClass, T> column) { 
     Callback<TableColumn<MyClass, T>, TableCell<MyClass, T>> cellFactory 
     = new Callback<TableColumn<MyClass, T>, TableCell<MyClass, T>>() { 
      @Override 
      public TableCell<MyClass, T> call(TableColumn<MyClass, T> param) { 
       // fill with life 
       return new TableCell<>(); 
      } 
     }; 
     column.setCellFactory(cellFactory); 
    } 
} 

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

+0

Итак, какова основная причина проблемы? Почему вопросительные знаки отлично работают в других случаях? В моих других образцах он работал, даже если он произошел несколько раз. Что отличает этот случай от других? PS Я знаю, что такое знак вопроса. Я просто не понимаю, почему это не работает в некоторых случаях. – Dims

+0

Поскольку я не знаю, к какому случаю вы обращаетесь и что там работает, я не могу сказать вам, почему они работают. Метод 'setCellFactory' требует, чтобы аргумент' Callback' был совместим с типом 'TableColumn', и это просто невозможно проверить с помощью'? '. Хорошо разработанные API будут использовать '? расширяет ... 'и'? super ... 'для таких обратных вызовов, что позволяет использовать более широкие типы, т. е. обратный вызов, потребляющий произвольные' Object', будет осуществимым, но мы говорим о JavaFX здесь ... – Holger

+1

Основная причина: 'setCellFactory (обратный вызов , TableCell > значение) 'означает, что оба типа должны использовать * тот же *' T', но '?' не такой же, как '?', поэтому, когда вы создаете 'Callback , TableCell >', это не сработает. 'T' может быть« неизвестным », но он должен быть * одним и тем же« неизвестным », а не двумя разными неизвестными. Метод 'DoubleQuestionMark3.call()' оставляет неопределенное значение 'T', но гарантируется, что значение параметра и возвращаемого значения будет таким же' T', поэтому это работает. – Andreas