原文链接 http://my.oschina.net/lujianing/blog/214404?fromerr=J9rsB7TB
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是安全简单。
Java 泛型
目录[-]
• 1.泛型类
• 1.1普通泛型
• 1.2 K/V泛型
• 2.泛型接口
• 3.泛型方法
• 4.限制泛型
• 5.通配泛型
• 6.补充
1.泛型类
1.1普通泛型
class Test < T > { private T obj; public void setValue ( T obj ) { this.obj = obj; } public T getValue () { System.out.println( obj.getClass().getName() ); return obj; } } /** * 测试泛型类 */ public class TestOne { public static void main ( String[] args ) { //测试Integer泛型 Test< Integer > t1 = new Test< Integer >(); t1.setValue( 5 ); Integer i = t1.getValue(); System.out.println( i ); //测试Double泛型 Test< Double > t2 = new Test< Double >(); t2.setValue( 5.55D ); Double d = t2.getValue(); System.out.println( d ); //测试String泛型 Test< String > t3 = new Test< String >(); t3.setValue( "hello world" ); String str = t3.getValue(); System.out.println( str ); } }
java.lang.Integer
5
java.lang.Double
5.55
java.lang.String
hello world
1.2 K/V泛型
class TestKV < K, V > { private Map< K, V > map = new HashMap< K, V >(); public void put ( K k, V v ) { map.put( k, v ); } public V get ( K k ) { return map.get( k ); } } public class TestFour { public static void main ( String[] args ) { TestKV< String, String > t = new TestKV< String, String >(); t.put( "name", "jianing" ); System.out.println( t.get( "name" ) ); TestKV< String, Integer > t2 = new TestKV< String, Integer >(); t2.put( "age", 24 ); System.out.println( t2.get( "age" ) ); } }
2.泛型接口
/** * 泛型接口 */ public interface TestImpl < T > { public void setValue ( T t ); public T getValue (); } /** * 泛型接口 Integer实现 */ class One implements TestImpl< Integer > { private Integer i; public void setValue ( Integer integer ) { i = integer; } public Integer getValue () { return i; } } /** * 泛型接口String实现 */ class Two implements TestImpl< String > { private String str; public void setValue ( String s ) { str = s; } public String getValue () { return str; } } /** * 泛型接口测试 */ public class TestTwo { public static void main ( String[] args ) { TestImpl one = new One(); one.setValue( 1 ); System.out.println( one.getValue() ); TestImpl two = new Two(); two.setValue( "hello word" ); System.out.println( two.getValue() ); } }
输出结果:
1
hello word
3.泛型方法
/** * 泛型方法类 */ class TestMethod { /** * 泛型方法 */ public < T > T getValue ( Object s, Class< T > clazz ) { System.out.println( clazz.getName() ); T t = null; if ( clazz.getName().equals( "java.lang.Integer" ) ) { Double d = Double.parseDouble( s.toString() ); int i = d.intValue(); t = ( T ) new Integer( i ); } if ( clazz.getName().equals( "java.lang.Double" ) ) { t = ( T ) new Double( s.toString() ); } return t; } } /** * 泛型方法测试类 */ public class TestThree { public static void main ( String[] args ) { TestMethod t = new TestMethod(); int i = t.getValue( "30.0011", Integer.class ); System.out.println( i ); double d = t.getValue( "40.0022", Double.class ); System.out.println( d ); } }
java.lang.Integer
30
java.lang.Double
40.0022
4.限制泛型
在上面的例子中,没有限制class Test<T>类型持有者T的范围,默认限定类型相当于Object。比如我们要限制T为数字接口类型。只需要这么做:class Test<T extends Number>,这样类中的泛型T只能是Number接口的实现类,传入非Number接口编译会出错。
5.通配泛型
/** * 通配泛型 */ public class TestFive { public static void main ( String[] args ) { Map< String, Class< ? extends Number > > map = new HashMap< String, Class< ? extends Number > >(); map.put( "Integer", Integer.class ); map.put( "Double", Double.class ); for ( Map.Entry< String, Class< ? extends Number > > entry : map.entrySet() ) { System.out.println( "key:" + entry.getKey() + " value:" + entry.getValue() ); } } }
key:Double value:class java.lang.Double
key:Integer value:class java.lang.Integer
简单的例子:针对1.1的例子
public static void main ( String[] args ) { //测试Integer泛型 Test< Integer > t1 = new Test< Integer >(); t1.setValue( 5 ); fun( t1 ); //测试Double泛型 Test< Double > t2 = new Test< Double >(); t2.setValue( 5.55D ); fun( t2 ); } public static void fun ( Test< ? > t ) { System.out.println( "通配泛型" + t.getValue() ); }
6.补充
在泛型中,可能会遇到<T><E>等,T和E分别是Type和Element的首字母。E一般用来表示集合类型中的元素的类型,例如List接口的定义,public interface List<E> extends Collection<E>。这只是一种命名习惯,两者没有本质区别。
===============================================================================================================
发现这片博文也很好:推荐一下http://my.oschina.net/caiyuan/blog/14109
1普通泛型
class Point < T > { // 此处可以随便写标识符号,T是type的简称 private T var; // var的类型由T指定,即:由外部指定 public T getVar () { // 返回值的类型由外部决定 return var; } public void setVar ( T var ) { // 设置的类型也由外部决定 this.var = var; } }; public class GenericsDemo06 { public static void main ( String args[] ) { Point< String > p = new Point< String >(); // 里面的var类型为String类型 p.setVar( "it" ); // 设置字符串 System.out.println( p.getVar().length() ); // 取得字符串的长度 } };
class Notepad < K, V > { // 此处指定了两个泛型类型 private K key; // 此变量的类型由外部决定 private V value; // 此变量的类型由外部决定 public K getKey () { return this.key; } public V getValue () { return this.value; } public void setKey ( K key ) { this.key = key; } public void setValue ( V value ) { this.value = value; } }; public class GenericsDemo09 { public static void main ( String args[] ) { Notepad< String, Integer > t = null; // 定义两个泛型类型的对象 t = new Notepad< String, Integer >(); // 里面的key为String,value为Integer t.setKey( "汤姆" ); // 设置第一个内容 t.setValue( 20 ); // 设置第二个内容 System.out.print( "姓名;" + t.getKey() ); // 取得信息 System.out.print( ",年龄;" + t.getValue() ); // 取得信息 } };
2通配符
class Info < T > { private T var; // 定义泛型变量 public void setVar ( T var ) { this.var = var; } public T getVar () { return this.var; } public String toString () { // 直接打印 return this.var.toString(); } }; public class GenericsDemo14 { public static void main ( String args[] ) { Info< String > i = new Info< String >(); // 使用String为泛型类型 i.setVar( "it" ); // 设置内容 fun( i ); } public static void fun ( Info< ? > temp ) { // 可以接收任意的泛型对象 System.out.println( "内容:" + temp ); } };
class Info < T > { private T var; // 定义泛型变量 public void setVar ( T var ) { this.var = var; } public T getVar () { return this.var; } public String toString () { // 直接打印 return this.var.toString(); } }; public class GenericsDemo17 { public static void main ( String args[] ) { Info< Integer > i1 = new Info< Integer >(); // 声明Integer的泛型对象 Info< Float > i2 = new Info< Float >(); // 声明Float的泛型对象 i1.setVar( 30 ); // 设置整数,自动装箱 i2.setVar( 30.1f ); // 设置小数,自动装箱 fun( i1 ); fun( i2 ); } public static void fun ( Info< ? extends Number > temp ) { // 只能接收Number及其Number的子类 System.out.print( temp + "、" ); } }; ---------------------------------------------------------- class Info < T > { private T var; // 定义泛型变量 public void setVar ( T var ) { this.var = var; } public T getVar () { return this.var; } public String toString () { // 直接打印 return this.var.toString(); } }; public class GenericsDemo21 { public static void main ( String args[] ) { Info< String > i1 = new Info< String >(); // 声明String的泛型对象 Info< Object > i2 = new Info< Object >(); // 声明Object的泛型对象 i1.setVar( "hello" ); i2.setVar( new Object() ); fun( i1 ); fun( i2 ); } public static void fun ( Info< ? super String > temp ) { // 只能接收String或Object类型的泛型 System.out.print( temp + "、" ); } };
4泛型无法向上转型
class Info < T > { private T var; // 定义泛型变量 public void setVar ( T var ) { this.var = var; } public T getVar () { return this.var; } public String toString () { // 直接打印 return this.var.toString(); } }; public class GenericsDemo23 { public static void main ( String args[] ) { Info< String > i1 = new Info< String >(); // 泛型类型为String Info< Object > i2 = null; i2 = i1; //这句会出错 incompatible types } };
nterface Info < T > { // 在接口上定义泛型 public T getVar (); // 定义抽象方法,抽象方法的返回值就是泛型类型 } 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; } }; public class GenericsDemo24 { public static void main ( String arsg[] ) { Info< String > i = null; // 声明接口对象 i = new InfoImpl< String >( "汤姆" ); // 通过子类实例化对象 System.out.println( "内容:" + i.getVar() ); } }; ---------------------------------------------------------- interface Info < T > { // 在接口上定义泛型 public T getVar (); // 定义抽象方法,抽象方法的返回值就是泛型类型 } class InfoImpl implements Info< String > { // 定义泛型接口的子类 private String var; // 定义属性 public InfoImpl ( String var ) { // 通过构造方法设置属性内容 this.setVar( var ); } public void setVar ( String var ) { this.var = var; } public String getVar () { return this.var; } }; public class GenericsDemo25 { public static void main ( String arsg[] ) { Info i = null; // 声明接口对象 i = new InfoImpl( "汤姆" ); // 通过子类实例化对象 System.out.println( "内容:" + i.getVar() ); } };
class Demo { public < T > T fun ( T t ) { // 可以接收任意类型的数据 return t; // 直接把参数返回 } }; public class GenericsDemo26 { public static void main ( String args[] ) { Demo d = new Demo(); // 实例化Demo对象 String str = d.fun( "汤姆" ); // 传递字符串 int i = d.fun( 30 ); // 传递数字,自动装箱 System.out.println( str ); // 输出内容 System.out.println( i ); // 输出内容 } };
7通过泛型方法返回泛型类型实例
class Info < T extends Number > { // 指定上限,只能是数字类型 private T var; // 此类型由外部决定 public T getVar () { return this.var; } public void setVar ( T var ) { this.var = var; } public String toString () { // 覆写Object类中的toString()方法 return this.var.toString(); } }; public class GenericsDemo27 { public static void main ( String args[] ) { Info< Integer > i = fun( 30 ); System.out.println( i.getVar() ); } public static < T extends Number > Info< T > fun ( T param ) {//方法中传入或返回的泛型类型由调用方法时所设置的参数类型决定 Info< T > temp = new Info< T >(); // 根据传入的数据类型实例化Info temp.setVar( param ); // 将传递的内容设置到Info对象的var属性之中 return temp; // 返回实例化对象 } };
class Info < T > { // 指定上限,只能是数字类型 private T var; // 此类型由外部决定 public T getVar () { return this.var; } public void setVar ( T var ) { this.var = var; } public String toString () { // 覆写Object类中的toString()方法 return this.var.toString(); } }; public class GenericsDemo28 { public static void main ( String args[] ) { Info< String > i1 = new Info< String >(); Info< String > i2 = new Info< String >(); i1.setVar( "HELLO" ); // 设置内容 i2.setVar( "汤姆" ); // 设置内容 add( i1, i2 ); } public static < T > void add ( Info< T > i1, Info< T > i2 ) { System.out.println( i1.getVar() + " " + i2.getVar() ); } };
public class GenericsDemo30 { public static void main ( String args[] ) { Integer i[] = fun1( 1, 2, 3, 4, 5, 6 ); // 返回泛型数组 fun2( i ); } public static < T > T[] fun1 ( T... arg ) { // 接收可变参数 return arg; // 返回泛型数组 } public class GenericsDemo30 { public static void main ( String args[] ) { Integer i[] = fun1( 1, 2, 3, 4, 5, 6 ); // 返回泛型数组 fun2( i ); } public static < T > T[] fun1 ( T... arg ) { // 接收可变参数 return arg; // 返回泛型数组 } public static < T > void fun2 ( T param[] ) { // 输出 System.out.print( "接收泛型数组:" ); for ( T t : param ) { System.out.print( t + "、" ); } } };
10泛型的嵌套设置
class Info < T, V > { // 接收两个泛型类型 private T var; private V value; public Info ( T var, V value ) { this.setVar( var ); this.setValue( value ); } public void setVar ( T var ) { this.var = var; } public void setValue ( V value ) { this.value = value; } public T getVar () { return this.var; } public V getValue () { return this.value; } }; 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; } }; public class GenericsDemo31 { public static void main ( String args[] ) { Demo< Info< String, Integer > > d = null; // 将Info作为Demo的泛型类型 Info< String, Integer > i = null; // Info指定两个泛型类型 i = new Info< String, Integer >( "汤姆", 30 ); // 实例化Info对象 d = new Demo< Info< String, Integer > >( i ); // 在Demo类中设置Info类的对象 System.out.println( "内容一:" + d.getInfo().getVar() ); System.out.println( "内容二:" + d.getInfo().getValue() ); } };