java泛型学习示例

Java泛型(Generics)是JDK5开始引入的一个新特性,允许在定义类和接口的时候使用类型参数(Type Parameter)。声明的类型参数在使用时用具体的类型来替换,现在泛型最主要的应用是在JDK5中的新集合类框架中,Map, List均有用到。其中的优点不言而喻,我们可以横向扩展更多的类,缺点呢,其实也就是他的优点,因为这需要我们在使用泛型类的时候,要很清楚自己的代码目地,不能使用错误的类型。

最基本的泛型类


代码如下:

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());

}

}

多个泛型类型


代码如下:

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());

}

}

在方法参数中使用通配符"?"


代码如下:

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);

}

}

向上转型失败


代码如下:

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;

}

}

泛型在接口中的使用

代码如下:

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());

}

}

通配符和extends, 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);

}

}

方法泛型,方法里面多个泛型


代码如下:

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);

}

}

方法中传入或返回的泛型类型由调用方法时所设置的参数类型决定

代码如下:

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;

}

}

让方法中传入两个参数类型保持一致


代码如下:

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());

}

}

泛型,可变参数,类似于javascript里的Arguments对象


代码如下:

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 + " ,");

}

}

}

泛型嵌套:使用泛型类做为参数;根据返回值类型确定返回值


代码如下:

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);

}

}

(0)

相关推荐

  • Java中的泛型详解

    所谓泛型:就是允许在定义类.接口指定类型形参,这个类型形参在将在声明变量.创建对象时确定(即传入实际的类型参数,也可称为类型实参) 泛型类或接口 "菱形"语法 复制代码 代码如下: //定义   public interface List<E> extends Collection<E>    public class HashMap<K,V> extends AbstractMap<K,V>  implements Map<K,V

  • 多个java泛型示例分享

    1.泛型类 1.1普通泛型 复制代码 代码如下: package test.lujianing;/** * 泛型类 * @param <T> */class Test<T>{    private T obj;    public void setValue(T obj){        this.obj =obj;    }    public T getValue(){        System.out.println(obj.getClass().getName());  

  • java 泛型的详解及实例

    java 泛型的详解及实例 Java在1.5版本中增加了泛型,在没有泛型之前,从集合中读取每一个对象都需要进行强转,如果一不小心插入了类型错误的对象,在运行时就会报错,给日常开发带来了很多不必要的麻烦,比如以下代码: public class TestGeneric { public static void main(String[] args) { List list = new ArrayList(); list.add(" name:"); list.add(" zer

  • 解析Java的Jackson库中对象的序列化与数据泛型绑定

    Jackson对象序列化 这里将介绍将Java对象序列化到一个JSON文件,然后再读取JSON文件获取转换为对象.在这个例子中,创建了Student类.创建将有学生对象以JSON表示在一个student.json文件. 创建一个名为JacksonTester在Java类文件在 C:\>Jackson_WORKSPACE. 文件: JacksonTester.java import java.io.File; import java.io.IOException; import org.codeh

  • 基于java中泛型的总结分析

    要我直接说出泛型是个what我还真讲不出来,这里先由一道问题引入: 定义一个坐标点类,要求能保存各种类型的数据,如:整形,浮点型,和字符串类型 既然变量类型起先不确定,那么很容易想到就是用所有类型的父类,也就是Object类来代替 不废话了,用代码来体现 实例1:用Object来实现不确定的数据类型输入 复制代码 代码如下: //这是定义的坐标点类class Point {    private Object x;    private Object y; //用Object来表示不确定的类型 

  • Java8中对泛型目标类型推断方法的改进

    一.简单理解泛型 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.通俗点将就是"类型的变量".这种类型变量可以用在类.接口和方法的创建中. 理解Java泛型最简单的方法是把它看成一种便捷语法,能节省你某些Java类型转换(casting)上的操作: 复制代码 代码如下: List<Apple> box = new ArrayList<Apple>();box.add(new Apple());Apple a

  • Java编程思想里的泛型实现一个堆栈类 分享

    觉得作者写得太好了,不得不收藏一下. 对这个例子的理解: //类型参数不能用基本类型,T和U其实是同一类型. //每次放新数据都成为新的top,把原来的top往下压一级,通过指针建立链接. //末端哨兵既是默认构造器创建出的符合end()返回true的节点. 复制代码 代码如下: //: generics/LinkedStack.java// A stack implemented with an internal linked structure.package generics; publi

  • java泛型学习示例

    Java泛型(Generics)是JDK5开始引入的一个新特性,允许在定义类和接口的时候使用类型参数(Type Parameter).声明的类型参数在使用时用具体的类型来替换,现在泛型最主要的应用是在JDK5中的新集合类框架中,Map, List均有用到.其中的优点不言而喻,我们可以横向扩展更多的类,缺点呢,其实也就是他的优点,因为这需要我们在使用泛型类的时候,要很清楚自己的代码目地,不能使用错误的类型. 最基本的泛型类 复制代码 代码如下: package com.garinzhang.jav

  • java单例模式学习示例

    单例模式有一下特点:1.单例类只能有一个实例.2.单例类必须自己自己创建自己的唯一实例.3.单例类必须给所有其他对象提供这一实例.单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.这些应用都或多或少具有资源管理器的功能.每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中.每台计算机可以有若干通信端口,系统应当集中管理这些通信端

  • Java中泛型学习之细节篇

    目录 简介 正文 什么是类型参数 为啥要有泛型 泛型的演变史 类型擦除 泛型的应用场景 通配符限定 动态类型安全检查 总结 简介 泛型的作用就是把类型参数化,也就是我们常说的类型参数 平时我们接触的普通方法的参数,比如public void fun(String s):参数的类型是String,是固定的 现在泛型的作用就是再将String定义为可变的参数,即定义一个类型参数T,比如public static <T> void fun(T t);这时参数的类型就是T的类型,是不固定的 从上面的S

  • 浅谈三分钟学习Java泛型中T、E、K、V、?的含义

    泛型是Java中一个非常重要的内容,对于Java进阶学习是必须要掌握的知识点之所以说这个知识点重要,如果你有过阅读过一些开源框架的代码,那你一定会看到源码中有很多地方使用到了泛型. 随便举两个例子,一个List,一个Map. 看了上面的源码,简单聊一下泛型,也就是回顾一下泛型的相关知识,来源百度百科. [泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法.Java语

  • Java中泛型的示例详解

    目录 泛型概述 使用泛型的好处 泛型的定义与使用 定义和使用含有泛型的类 含有泛型的方法 含有泛型的接口 泛型通配符 通配符基本使用 通配符高级使用----受限泛型 泛型概述 我们都知道集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型.当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换. 大家观察下面代码: public class GenericDemo { public static void main(String[] args) {

  • Java泛型定义与用法入门示例

    本文实例讲述了Java泛型定义与用法.分享给大家供大家参考,具体如下: 一 引入泛型背景 Java集合不会知道它们需要用它来保存什么类型的对象,所以他们把集合设计成能保存任何类型的对象,只要求具有很好的通用性.但这样做也带来两个问题: 集合对元素类型没有任何限制,这样可能引发一些问题:例如想创建一个只能保存Dog对象的集合,但程序也可以轻易地将Cat对象"丢"进去,所以可能引发异常. 由于把对象"丢进"集合时,集合丢失了对象的状态信息,集合只知道它盛装的是Objec

  • Java泛型的继承和实现操作示例

    本文实例讲述了Java泛型的继承和实现操作.分享给大家供大家参考,具体如下: 一 点睛 泛型类和泛型接口被定义后,是可以被继承和实现的. 二 泛型类的继承 1 代码 class A<E> { E t; } public class B<T,T1>extends A<T>{ public static void main(String[] args){ System.out.println("B test"); } } 2 运行 B test 3 说明

  • Java不可不知的泛型使用示例代码

    本文介绍了Java的泛型的基本使用. 1. 为什么使用泛型 看下面一个例子: 为了说明问题,本类写的尽量简陋,请把目光主要放在类型上. /** * @author Xing Xiaoguan (xingrenguanxue) */ public class MyArrayList { private int[] elementData; private int size = 0; public MyArrayList(int capacity) { elementData = new int[c

  • Java泛型的类型擦除示例详解

    目录 前言 泛型的类型擦除原则是: 1 擦除类定义中的类型参数 1.1 无限制类型擦除 1.2 有限制类型擦除 2 擦除方法定义中的类型参数 3 桥接方法和泛型的多态 总结 参考资料 前言 Java泛型这个特性是从JDK 1.5才开始加入的,因此为了兼容之前的版本,Java泛型的实现采取了"伪泛型"的策略,即Java在语法上支持泛型,但是在编译阶段会进行所谓的"类型擦除"(Type Erasure),将所有的泛型表示(尖括号中的内容)都替换为具体的类型(其对应的原生

  • 一看就懂 详解JAVA泛型通配符T,E,K,V区别

    1. 先解释下泛型概念 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法.Java语言引入泛型的好处是安全简单. 在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的"任意化","任意化"带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的.对于强制类型转

随机推荐