Java generics " capture de?"


Je travaille avec un {[3] } et lors du changement d'usine de cellules, je dois passer un

Callback<TreeTableColumn<A, capture of ?>, TreeTableCell<A, capture of ?>>

Où A est une classe avec laquelle je travaille mais je ne sais pas comment travailler avec la "capture de ?"

J'ai essayé de créer

new Callback<TreeTableColumn<A, ?>, TreeTableCell<A, ?>>

Mais L'IDÉE montre l'avertissement

setCellFactory(Callback<TreeTableColumn<A, capture<?>>, TreeTableCell<A, capture<?>>>) in TreeTableColumn cannot be applied to (anonymous Callback<TreeTableColumn<A, ?>, TreeTableCell<A, ?>>)

J'ai essayé d'utiliser des classes spécifiques (comme String) au lieu de "?"ainsi, mais rien n'y fit.

Quelqu'un Pourrait-il m'expliquer comment travailler avec cela?

Merci vous.

MODIFIER:

J'ai recueilli un peu plus d'informations.. le CellFactory de TreeTableColumn<S,T> devrait être Callback<TreeTableColumn<S,T>,TreeTableCell<S,T>>, cependant, le TreeTableColumn avec lequel je travaille est créé en tant que type brut (dans une bibliothèque).

L'utilisation d'un rappel de type brut fonctionne. Mais y a-t-il d'autres options pour résoudre ce problème?

Author: roeygol, 2016-10-24

2 answers

Un caractère générique représente un type inconnu.

la capture de caractères génériques est le processus de liaison de la valeur d'un type générique à une nouvelle variable de type. Par exemple:

List<?> list = ...;
shuffle(list);

<T> void shuffle(List<T> list) {
    ...
}

Ici, la valeur inconnue de ? est lié à la nouvelle variable de type T lors de l'invocation de la shuffle méthode, permettant la lecture aléatoire méthode de référer à ce type.

Le compilateur Java représente en interne la valeur d'un caractère générique en le capturant dans une variable de type anonyme, qu'elle appelle " capture of ?"(en fait, javac les appelle " capture # 1 de ?"parce que différentes utilisations de ? peuvent se référer à différents types, et donc avoir des captures différentes).

Ok, alors qu'est-ce qui ne va pas dans votre code? Vous essayez d'invoquer une méthode

<S,T> setCellFactory(Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> factory);

Avec

Callback<TreeTableColumn<S,?>, TreeTableCell<S, ?>> factory;

Dans la signature de méthode, le paramètre de type T représente un seul type, qui doit être fourni par l'appelant. Par commodité, le compilateur tente automatiquement pour déduire une valeur appropriée (- >type inference). Votre erreur de compilation signifie que le compilateur n'a pas pu le faire.

Dans ce cas, ce n'est pas une lacune de l'inférence de type, car il est en fait impossible d'attribuer une valeur appropriée à T, car les deux ? doivent être des sous-types de T, mais le compilateur ne peut pas savoir que les deux ? représentent le même type, ou même des types connexes.

Pour appeler cette méthode avec succès, votre type d'argument doit utiliser le même type pour toutes les occurrences de T. Si vous avez déjà un tel type à portée de main, allez-y et utilisez-le. Sinon, vous pourrez peut-être en introduire un en utilisant la capture générique:

setCellFactory(newFactory());

<S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> newFactory() {
    return new Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> {
        ...
    }
}
 21
Author: meriton, 2016-11-03 14:12:18

D'après ce que j'ai trouvé de qu'est ce qu'une capture de conversion et oracle de capture générique docs il semble que vous soyez confronté à un problème où le compilateur ne peut pas trouver la classe d'aide nécessaire, ou essaie d'y placer un objet, mais ce que vous lui donnez ne peut pas être converti en toute sécurité.

MODIFIER:

DEFAULT_CELL_FACTORY

public static final Callback<TreeTableColumn<?,?>,TreeTableCell<?,?>>

Si aucune cellFactory n'est spécifiée sur une instance TreeTableColumn, alors celui-ci sera utilisé par défaut. À l'heure actuelle, il rend simplement le Propriété TableCell item dans la propriété graphique si l'élément est un Node, ou il appelle simplement toString() s'il n'est pas null, en définissant le chaîne résultante à l'intérieur de la propriété text.

Et

SetCellFactory

public final void setCellFactory(Callback<TreeTableColumn<S,T>,TreeTableCell<S,T>> value)

Définit la valeur de la propriété cellFactory. Description de la propriété: La fabrique de cellules pour toutes les cellules de cette colonne. L'usine de cellules est responsable du rendu données contenues dans chaque TreeTableCell pour une seule TreeTableColumn. Par défaut, TreeTableColumn utilise une usine de cellules par défaut, mais cela peut être remplacé par une implémentation personnalisée, par exemple pour afficher les données d'une manière différente ou pour prendre en charge l'édition. Il y a beaucoup de documentation sur la création d'usines de cellules personnalisées ailleurs (voir Cell et TreeTableView par exemple).

Enfin, il existe un certain nombre d'usines de cellules pré-construites disponibles dans javafx.scène.contrôle.cellule paquet.

Extrait de Java 8 API Doc.

Donc quelque chose comme ça devrait aller plus dans la bonne direction:

public static <S> Callback<TableColumn<S,String>, TableCell<S,String>> forTableColumn() {
   return forTableColumn(new DefaultStringConverter());
}

Ou quelque chose comme ça en fonction de ce que vous voulez donner dans la cellule.

setCellFactory(TextFieldTableCell.<DataModel, Integer>forTableColumn(new IntegerStringConverter()));

Ces extraits de code sont tirés de Ce thread StackOverflow

Et enfin ce lien pourrait vous aider aussi: TableView Cellule Tutoriel

Donc cela devrait vous donner un peu plus de lumière dans le noir sur quoi peut-être l'origine du problème.

 2
Author: Nico, 2017-05-23 11:47:11