有关java泛型中一段简单代码 擦除知识点的疑问
ringa_lee
ringa_lee 2017-04-17 17:35:11
0
6
839
  1. 下面这个程序中T 类型不是被擦除了吗?为什么使用get ( ) 方法不需要类型装换? (不适用泛型的简单代码就需要加(String) 来实现类型转换)

  2. 擦除知识点在实际编程中体现的多吗?

代码如下:

public class GenericHolder<T> {
  private T obj;
  public void set(T obj) { this.obj = obj; }
  public T get() { return obj; }
  public static void main(String[] args) {
    GenericHolder<String> holder =
      new GenericHolder<String>();
    holder.set("Item");
    String s = holder.get();
  }
}
public class SimpleHolder {
  private Object obj;
  public void set(Object obj) { this.obj = obj; }
  public Object get() { return obj; }
  public static void main(String[] args) {
    SimpleHolder holder = new SimpleHolder();
    holder.set("Item");
    String s = (String)holder.get();
  }
}
ringa_lee
ringa_lee

ringa_lee

répondre à tous(6)
伊谢尔伦

L'effacement signifie qu'aucune information sur les paramètres génériques ne peut être obtenue à l'intérieur de la classe générique au moment de l'exécution. Si la limite est spécifiée, le type réel de la variable générique est la limite. Le code dans l'exemple de l'affiche ne spécifie pas la limite. , donc effacez vers Object, c'est-à-dire que le type d'exécution réel d'obj est Object. La raison pour laquelle l'utilisation de la méthode get() ne nécessite pas de conversion de type forcée est que le compilateur génère le code de conversion pour vous lors de la compilation. , La situation après traitement est probablement similaire à String s = (String)holder.get() dans la méthode principale de l'exemple 2. Pour plus de détails, l'auteur peut utiliser javap pour décompiler et afficher.

Concernant la deuxième question, je pense que c'est la même chose que de savoir si vous lisez ou non le code source. Cela n'affecte pas la programmation si vous ne le lisez pas. Mais après l'avoir lu, je comprends que ce sera très. facile à écrire. Je suis encore étudiant et en fait je ne connais pas la situation, juste un petit avis~

.
阿神

Les génériques ne sont reflétés que dans le code source, et après compilation, ils sont équivalents au dernier exemple que vous avez donné. Par conséquent, le test public void (List<String> list) et le public void test (List<Integer> list) ne peuvent pas être surchargés.

Peter_Zhu
  1. L'effacement se fait lors de la compilation, lorsque les fichiers java sont compilés en fichiers de classe. Les génériques de Java peuvent être considérés comme une sorte de sucre syntaxique, ce qui nous rend plus sûr et plus pratique lors de l'écriture de code Java.

  2. L'effacement n'est pas utilisé dans le travail réel. L'effacement peut être considéré comme une action d'interprétation du sucre de syntaxe générique au moment de la compilation.

刘奇
  • Lors de l'utilisation de la classe générique T new, T est spécifié comme String et ses variables membres sont également String. Aucune transformation n'est requise. Cependant, le membre d'une autre classe est Object, et new
    ne l'est pas. spécifié, donc une transformation est nécessaire.

  • L'effacement n'est généralement pas utilisé dans le travail réel.

黄舟

1. Tout d'abord, l'effacement signifie que les balises génériques sont transmises au compilateur Javac pour qu'il s'exécute et fonctionne. Une fois que le code a dépassé la période de compilation, "T" est ignoré pendant le fonctionnement et T est introuvable dans le fichier de classe. Ici, vous indiquez que le type est <String>, puis le compilateur convertira le T contenu dans GenericHolder en type String lors de la compilation. Votre get n'a donc pas besoin d'être transformé (le compilateur a déjà reconnu String).

2. L’effacement est un concept très important dans les génériques. On peut dire que si vous ne comprenez pas l’effacement, vous ne comprenez pas les génériques. Ce qui est courant et pertinent dans le travail réel est la sérialisation et la désérialisation d'objets, qui sont utilisées dans des frameworks tels que gson.

刘奇

GenericHolder<String> dans

private T obj;
public void set(T obj) { this.obj = obj; }
public T get() { return obj; }

équivaut à

private Object obj;
public void set(Object obj) { this.obj = obj; }
public Object get() { return (Object) obj; }
...
String s = (String) holder.get();

C'est en fait juste du sucre de syntaxe

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal