Java 泛型-泛型类、泛型方法、泛型接口、通配符、上下限

原创 2016年06月02日 11:09:50

泛型:

        一种程序设计语言的新特性,于Java而言,在JDK 1.5开始引入。泛型就是在设计程序的时候定义一些可变部分,在具体使用的时候再给可变部分指定具体的类型。使用泛型比使用Object变量再进行强制类型转换具有更好的安全性和可读性。在Java中泛型主要体现在泛型类、泛型方法和泛型接口中。


泛型类:

        当一个类要操作的引用数据类型不确定的时候,可以给该类定义一个形参。用到这个类的时候,通过传递类型参数的形式,来确定要操作的具体的对象类型。在JDK1.5之前,为了提高代码的通用性,通常把类型定义为所有类的父类型:Object,这样做有两大弊端:1. 在具体操作的时候要进行强制类型转换;2. 这样还是指定了类型,还是不灵活,对具体类型的方法未知且不安全。

        泛型类的格式:在类名后面声明类型变量<E>   ,泛型类可以有多个类型变量, 如:public class MyClass<K, V>


什么时候使用泛型类?

        只要类中操作的引用数据类型不确定,就可以定义泛型类。通过使用泛型类,可以省去强制类型转换和类型转化异常的麻烦。


 泛型类例子:

        在这里定义两个类:Teacher 和 Student,定义一个泛型类Util<E>,其中getE()的作用是根据传入的对象,返回具体的对象。在main()方法中,传入具体的类型为Student和Teacher,再进一步操作。

public class Generic {

	public static void main(String[] args) {
	      Util<Student> ts = new Util<Student>();
        System.out.println(ts.getE(new Student("Student","三年级" ,22)).getGrade());
        Util<Teacher> tt = new Util<Teacher>();
        System.out.println(tt.getE(new Teacher("Teacher",22)).getName());
		
	}
	
}
class Util<E>{
	public E getE(E e){
		return e;
	}
}

class Teacher{
	String name;
	int age;
	public Teacher() {
	}
	
	public Teacher(String name, int age){
		this.name = name;
		this.age = age;
	}
	 Some  Getter & Setter functions
}
class Student{
    String name;
    String grade;
    int number;
    
    public Student(String name, String grade, int number){
        this.name = name;
        this.grade = grade;
        this.number = number;
    }
    Some Getter & Setter functions
    
}


泛型方法:

         泛型方法也是为了提高代码的重用性和程序安全性。编程原则:尽量设计泛型方法解决问题,如果设计泛型方法可以取代泛型整个类,应该采用泛型方法。

        泛型方法的格式:类型变量放在修饰符后面和返回类型前面, 如:public static <E> E getMax(T... in)

泛型方法例子:

public class GenericFunc {

	public static void main(String[] args) {
		print("hahaha");
		print(200);
	}
	
	public static <T> void print(T t){
		System.out.println(t.toString());
	}

}

泛型接口:

        将泛型原理用于接口实现中,就是泛型接口。

      泛型接口的格式:泛型接口格式类似于泛型类的格式,接口中的方法的格式类似于泛型方法的格式。


泛型接口例子:

MyInterface.java

public interface MyInteface<T> {
	public T read(T t);
}

Generic2.java

public class Generic2 implements MyInterface<String>{

	public static void main(String[] args) {
		Generic2 g = new Generic2();
		System.out.println(g.read("hahaha"));
	}

	@Override
	public String read(String str) {
		return str;
	}

}

泛型通配符:

        当操作的不同容器中的类型都不确定的时候,而且使用的元素都是从Object类中继承的方法,这时泛型就用通配符“?”来表示。

泛型的通配符:“?”  相当于 “? extends Object


泛型通配符例子:

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

public class AllCollectionIterator {

	public static void main(String[] args) {
		HashSet<String> s1 = new HashSet<String>();
		s1.add("sss1");
		s1.add("sss2");
		s1.add("sss3");
		
		
		ArrayList<Integer> a1 = new ArrayList<Integer>();
		a1.add(1);
		a1.add(2);
		a1.add(3);
		a1.add(4);
		
		printAllCollection(a1);
		System.out.println("-------------");
		printAllCollection(s1);
	}
	
	public static void printAllCollection(Collection<?> c){
		Iterator<?> iter = c.iterator();
		while (iter.hasNext()) {
			System.out.println(iter.next().toString());
			
		}
	}

}

泛型限定:

        泛型限定就是对操作的数据类型限定在一个范围之内。限定分为上限和下限。

        上限:? extends E   接收E类型或E的子类型

        下限:? super E    接收E类型或E的父类型

        限定用法和泛型方法,泛型类用法一样,在“<>”中表达即可。

        一个类型变量或通配符可以有多个限定,多个限定用“&”分隔开,且限定中最多有一个类,可以有多个接口;如果有类限定,类限定必须放在限定列表的最前面。如:T extends MyClass1 & MyInterface1 & MyInterface2


      在Collection<E>接口中addAll()就用到泛型限定。

addAll(Collection<? extends E> c)
          将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。


泛型限定的例子:

        这个例子的作用是计算最大值。

import java.util.Calendar;
import java.util.GregorianCalendar;

public class GenericGetMax {

	public static void main(String[] args) {
		String[] inArrStr = {"haha", "test", "nba", "basketball"};
		System.out.println(GetMax.findMax(inArrStr).toString());
		Integer[] inArrInt = {11, 33, 2, 100, 101};
		System.out.println(GetMax.findMax(inArrInt));
		GregorianCalendar[] inArrCal = {
				new GregorianCalendar(2016, Calendar.SEPTEMBER, 22),
				new GregorianCalendar(2016, Calendar.OCTOBER, 10)};
		System.out.println(GetMax.findMax(inArrCal).toZonedDateTime());
	}
}

class GetMax {
	@SafeVarargs
	public static <T extends Comparable> T findMax(T... in) {
		T max = in[0];
		for (T one : in) {
			if (one.compareTo(max) > 0) {
				max = one;
			}
		}

		return max;
	}
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一

对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下。 本文参考java 泛型详解、Java中的泛型方法、 java泛型详解 1. 概...
  • s10461
  • s10461
  • 2016年12月30日 11:44
  • 28842

Java泛型:泛型类、泛型接口和泛型方法

泛型类 容器类应该算得上最具重用性的类库之一。 public class Container{ private String key; private String val...

Java<>泛型方法

问题:编写一个泛型方法add(),当传入不同数字类型的值时,能够进行加法运算,(如可以传入int、long、float、double类型,但要对传入的值做一定的限定,如必须是数字)。   解决:利...
  • lee_yaob
  • lee_yaob
  • 2012年07月10日 13:20
  • 28818

java 泛型详解-绝对是对泛型方法讲解最详细的

对Java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下。 本文参考java 泛型详解、Java中的泛型方法、 java泛型详解 1...

JAVA 泛型方法 和 静态方法泛型

//仅作为学习笔记 /* // 泛型方法和静态方法泛型 泛型类定义的泛型 在整个类中有效 如果被方法使用 那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定 ...

JAVA——泛型类和泛型方法(静态方法泛型)

泛型类定义的泛型,在整个类中有效。如果被方法是用,那么 泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。为了让不同的方法可以操作不同类型,而且类型还不确定。那么 可以将泛型定义在...

【Java】关于泛型:泛型类、泛型接口和泛型方法

有许多原因促成了泛型的出现,而最引人注意的一个原因,就是为了创建容器类。 泛型类 容器类应该算得上最具重用性的类库之一。先来看一个没有泛型的情况下的容器类如何定义: public c...
  • hj7jay
  • hj7jay
  • 2016年11月16日 10:36
  • 1172

Java中的泛型<T>类与方法

泛型就是变量类型的参数化。在使用泛型前,存入集合中的元素可以是任何类型的,当从集合中取出时,所有的元素都是Object类型,需要进行向下的强制类型转换,转换到特定的类型。而强制类型转换容易引起运行时错...

Java泛型详解

1. 概述 在引入范型之前,Java类型分为原始类型、复杂类型,其中复杂类型分为数组和类。引入范型后,一个复杂类型 就可以在细分成更多的类型。 例如原先的类型List,现在在细分成List, L...
  • Jinuxwu
  • Jinuxwu
  • 2011年09月13日 16:09
  • 238478

Java 泛型通配符?解惑

一、通配符的上界 既然知道List并不是List的子类型,那就需要去寻找替他解决的办法, 是AnimalTrianer.act()方法变得更为通用(既可以接受List类型,也可以接受List等参...
  • Baple
  • Baple
  • 2014年05月05日 15:53
  • 31546
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java 泛型-泛型类、泛型方法、泛型接口、通配符、上下限
举报原因:
原因补充:

(最多只允许输入30个字)