Maison > Java > javaDidacticiel > le corps du texte

exemples d'apprentissage des génériques Java

高洛峰
Libérer: 2017-01-18 11:08:44
original
1227 Les gens l'ont consulté

Java Generics (Generics) est une nouvelle fonctionnalité introduite dans JDK5, qui permet l'utilisation de paramètres de type (Type Parameter) lors de la définition de classes et d'interfaces. Les paramètres de type déclarés sont remplacés par des types spécifiques lorsqu'ils sont utilisés. L'application la plus importante des génériques se trouve désormais dans le nouveau cadre de classes de collection du JDK5, où Map et List sont utilisés. Les avantages sont évidents. Nous pouvons étendre davantage de classes horizontalement. Les inconvénients sont en fait ses avantages, car lorsque nous utilisons des classes génériques, nous devons être très clairs sur le but de notre code et ne pouvons pas utiliser de type.

La classe générique la plus basique

package com.garinzhang.javabase.generic.e1;
/**
* 最基本的泛型类,类型由自己定义
* @author Garin Zhang
*
* @param <T>
*/
public class Point<T> {
private T var;
public T getVar() {
return var;
}
public void setVar(T var) {
this.var = var;
}
}
package com.garinzhang.javabase.generic.e1;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Point<String> p = new Point<String> ();
p.setVar("coder");
System.out.println(p.getVar());
}
}
Copier après la connexion

Plusieurs types génériques

package com.garinzhang.javabase.generic.e2;
/**
* 多个泛型类型,一般多个最好是以靠近T的字母,如S,R等
* @author Garin Zhang
*
* @param <T>
* @param <S>
*/
public class Notepad<T, S> {
private T key;
private S value;
public T getKey() {
return this.key;
}
public S getValue() {
return this.value;
}
public void setKey(T key) {
this.key = key;
}
public void setValue(S value) {
this.value = value;
}
}
package com.garinzhang.javabase.generic.e2;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Notepad<String, Integer> p = new Notepad<String, Integer> ();
p.setKey("coder");
p.setValue(99999);
System.out.println("key: " + p.getKey());
System.out.println("value: " + p.getValue());
}
}
Copier après la connexion

Utiliser le caractère générique "?" dans les paramètres de méthode

package com.garinzhang.javabase.generic.e3;
/**
* 该例子关键在main方法里
* @author Garin Zhang
*
* @param <T>
*/
public class Info<T> {
private T key;
public T getKey() {
return this.key;
}
public void setKey(T key) {
this.key = key;
}
@Override
public String toString() {
return this.key.toString();
}
}
package com.garinzhang.javabase.generic.e3;
/**
* 在方法参数中使用通配符
* @author Garin Zhang
*
*/
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> i = new Info<String>();
i.setKey("coder");
fun(i);
Info<Integer> j = new Info<Integer>();
j.setKey(9999);
fun(j);
}
public static void fun(Info<?> temp) {
System.out.println("Content: " + temp);
}
}
Copier après la connexion

Upcast échec

package com.garinzhang.javabase.generic.e4;
/**
* 该例子关键在main方法里
* @author Garin Zhang
*
* @param <T>
*/
public class Info<T> {
private T key;
public T getKey() {
return this.key;
}
public void setKey(T key) {
this.key = key;
}
@Override
public String toString() {
return this.key.toString();
}
}
package com.garinzhang.javabase.generic.e4;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> strEg = new Info<String>();
Info<Object> objEg;
// 编译错误"Type mismatch: cannot convert from Info<String> to Info<Object>"
// 向上转型失败,String -> Object
// objEg = strEg;
}
}
Copier après la connexion

Utilisation de génériques dans les interfaces

package com.garinzhang.javabase.generic.e5;
/**
* 该例子关键在main方法里
* @author Garin Zhang
*
* @param <T>
*/
interface Info<T> {
public T getVar();
}
package com.garinzhang.javabase.generic.e5;
/**
* 泛型类
* @author Garin Zhang
*
* @param <T>
*/
public class InfoImpl<T> implements Info<T> {
private T var;
public InfoImpl(T var) {
this.setVar(var);
}
public void setVar(T var) {
this.var = var;
}
public T getVar() {
return this.var;
}
}
package com.garinzhang.javabase.generic.e5;
/**
* 非泛型类
* @author Garin Zhang
*
* @param <T>
*/
public class InfoImpl1 implements Info<String> {
private String var;
public InfoImpl1(String var) {
this.setVar(var);
}
public void setVar(String var) {
this.var = var;
}
public String getVar() {
return this.var;
}
}
package com.garinzhang.javabase.generic.e5;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> strEg = new InfoImpl<String>("coder");
System.out.println("Content: " + strEg.getVar());
Info<String> strEg1 = new InfoImpl1("coder1");
System.out.println("Content: " + strEg1.getVar());
}
}
Copier après la connexion

Wildcards et extensions, utilisation de super

package com.garinzhang.javabase.generic.e6;
/**
* 该例子关键在main方法里
* @author Garin Zhang
*
* @param <T>
*/
public class Info<T> {
private T key;
public T getKey() {
return this.key;
}
public void setKey(T key) {
this.key = key;
}
@Override
public String toString() {
return this.key.toString();
}
}
package com.garinzhang.javabase.generic.e6;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> strEg = new Info<String>();
strEg.setKey("coder");
// 编译报错"The method fun(Info<? extends Number>) in the type GenericExample is not applicable for the arguments (Info<String>)"
// upTypeLimit(i);
// 使用Integer,Number类型均可以
Info<Integer> intEg = new Info<Integer>();
intEg.setKey(9999);
upTypeLimit(intEg);
// 编译报错"The method downTypeLimit(Info<? super String>) in the type GenericExample is not applicable for the arguments (Info<Integer>)"
// downTypeLimit(intEg);
 
// 由于使用的是super,downTypeLimit只能接收String本身和Object
// 查看了String的继承关系,没有继承其他类,只有Object
downTypeLimit(strEg);
 
Info<Object> objEg = new Info<Object>();
objEg.setKey(999);
downTypeLimit(objEg);
}
/**
* <? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类
* @param temp
*/
public static void upTypeLimit(Info<? extends Number> temp) {
System.out.println("Content: " + temp);
}
 
/**
* <? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object
* 在此例中,表示T只能为Object或String,因为String只继承于Object
* @param temp
*/
public static void downTypeLimit(Info<? super String> temp) {
System.out.println("Content: " + temp);
}
}
Copier après la connexion

Méthode génériques, plusieurs génériques dans la méthode

package com.garinzhang.javabase.generic.e7;
/**
* 方法泛型,方法里面多个泛型
* @author Garin Zhang
*
* @param <T>
*/
public class Info {
/**
* 格式:方法修饰付 <以逗号隔开的类型列表>返回值类型方法名(参数列表)
* 例如:public <T, S> T fun(T t, S s)
* @param t
* @param s
* @return
*/
public <T, S> T fun(T t, S s) {
System.out.println(s.toString());
return t;
}
}
package com.garinzhang.javabase.generic.e7;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info info = new Info();
String str = info.fun("coder", "print second generic param");
System.out.println(str);
 
int i = info.fun(30, "print second param again");
System.out.println(i);
}
}
Copier après la connexion

Le type générique passé ou retourné dans la méthode est déterminé par le type de paramètre défini lors de l'appel de la méthode

package com.garinzhang.javabase.generic.e8;
/**
* extends
* @author Garin Zhang
*
* @param <T>
*/
public class Info<T extends Number> {
private T var;
public T getVar() {
return this.var;
}
public void setVar(T var) {
this.var = var;
}
@Override
public String toString() {
return this.var.toString();
}
}
package com.garinzhang.javabase.generic.e8;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<Integer> intEg = fun(30); // 这里类型已经确定为Integer
System.out.println(intEg.getVar());
}
/**
* 方法中传入或返回的泛型类型由调用方法时所设置的参数类型决定
* @param param
* @return
*/
public static <T extends Number> Info<T> fun(T param) {
Info<T> temp = new Info<T>();
temp.setVar(param);
return temp;
}
}
Copier après la connexion

Laissez la méthode être passée dans Les deux types de paramètres sont cohérents

package com.garinzhang.javabase.generic.e9;
/**
* 查看main
* @author Garin Zhang
*
* @param <T>
*/
public class Info<T> {
private T var;
public T getVar() {
return this.var;
}
public void setVar(T var) {
this.var = var;
}
@Override
public String toString() {
return this.var.toString();
}
}
package com.garinzhang.javabase.generic.e9;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> i1 = new Info<String>();
i1.setVar("Hello");
 
Info<String> i2 = new Info<String>();
i2.setVar("Coder");
 
Info<Integer> i3 = new Info<Integer>();
i3.setVar(999);
 
add(i1, i2);
 
//编译错误"The method add(Info<T>, Info<T>) in the type GenericExample is not applicable for the arguments (Info<String>, Info<Integer>)"
// add(i1, i3);
}
/**
* 方法中传入两个参数类型必须一致
* @param param
* @return
*/
public static <T> void add(Info<T> i1, Info<T> i2) {
System.out.println(i1.getVar() + ":" + i2.getVar());
}
}
Copier après la connexion

Paramètres génériques et variables, similaires à l'objet Arguments en JavaScript

package com.garinzhang.javabase.generic.e10;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Integer i[] = fun(1, 2, 3, 4, 5, 6);
fun2(i);
}
public static <T> T[] fun(T... arg) {
return arg;
}
public static <T> void fun2(T param[]) {
System.out.println("generic array: ");
for(T t : param) {
System.out.println(t + " ,");
}
}
}
Copier après la connexion

Imbrication générique : utiliser des classes génériques comme paramètres ; Déterminer la valeur de retour en fonction du type de valeur de retour

package com.garinzhang.javabase.generic.e11;
/**
* 接受两个泛型类型
* @author Garin Zhang
*
* @param <T>
*/
public class Info<T, V> {
private T var;
private V value;
 
public T getVar() {
return this.var;
}
public void setVar(T var) {
this.var = var;
}
 
public V getValue(){
return this.value;
}
public void setValue(V value) {
this.value = value;
}
@Override
public String toString() {
return this.var.toString();
}
}
package com.garinzhang.javabase.generic.e11;
/**
* 接受1个泛型类型
* @author Garin Zhang
*
* @param <T>
*/
public class Demo<S> {
private S info;
public Demo(S info) {
this.setInfo(info);
}
public void setInfo(S info) {
this.info = info;
}
public S getInfo() {
return this.info;
}
}
package com.garinzhang.javabase.generic.e11;
import java.util.List;
import com.google.common.collect.Lists;
public class GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Demo<Info<String, Integer>> d;
Info<String, Integer> i;
i = new Info<String, Integer>();
i.setVar("Coder");
i.setValue(999);
d = new Demo<Info<String,Integer>>(i);
System.out.println("Content: " + d.getInfo().getVar());
System.out.println("Content: " + d.getInfo().getValue());
System.out.println(query(1, 2, 3, 4, 5).toString()); // [1, 2, 3, 4, 5]
// 警告"Type safety: A generic array of Object&Comparable<?>&Serializable is created for a varargs parameter"
System.out.println(query(1, 2, 3, "StringType").toString()); // [1, 2, 3, StringType]
System.out.println(query("I ", "am ", "a ", "coder").toString());// [I , am , a , coder]
 
List<String> list = Lists.newArrayList("I ", "am ", "a ", "coder");
System.out.println(list.toString()); // [I , am , a , coder]
}
/**
* 通过返回值确定泛型类型,这个方法里面的返回值类型,是由方法的定义自动生成的
* @param elements
* @return
*/
public static <E> List<E> query(E... elements) {
// https://github.com/exitsoft/exit-web-framework/commit/1d2f1098a2a4b6abab175b793e2308aa8bd0ea16.
// import com.google.common.collect.Lists;
// <dependency>
// <groupId>com.google.guava</groupId>
// <artifactId>guava</artifactId>
// <version>16.0.1</version>
// </dependency>
return Lists.newArrayList(elements);
}
}
Copier après la connexion

Pour plus d'exemples d'apprentissage des génériques Java et d'articles connexes, veuillez prêter attention au site Web PHP chinois !

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!