Java_Generics泛型

本文详细介绍了Java泛型的概念、优势及其实现细节。包括泛型类、泛型方法、泛型接口的定义与使用,以及通配符、泛型限定等高级特性。通过示例代码展示了如何在实际开发中应用泛型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

1.泛型概述

   泛型(Generics),泛型是在jdk1.5以后出现的新特性,用于解决安全问题,是一个类型安全机制。
   使用泛型好处:
    (1).类型安全
提高 Java 程序的类型安全,通过知道使用泛型定义的变量的类型限制,将运行时期的类转换异常体现在编译时期;
    (2).消除强制类型转换  消除源代码中的许多强制类型转换,这使得代码更加可读,并且减少了出错机会;

    (3).潜在的性能收益 泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来可能。由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。

2.泛型修饰

   (1).自定义泛型

   (2).自定义泛型方法
   (3).自定义泛型接口

3.泛型实现细节

   (1).左右两侧泛型声明应相同

       Person<String> p1 = new Person<String>();

       Person<Integer> p2 = new Person<Integer>();

   (2).泛型左右范围

   可以限定集合中的输入类型,挡住源程序中非法字符输入,编译完成后,去掉所加的泛型信息。p1.getClass() == p2.getClass();//true

   (3).向指定了泛型的集合添加其它类型数据

		List<Integer> list = new ArrayList<Integer>();
		list.add(12);
		list.add(11);
		
		list.getClass().getMethod("add", Object.class).invoke(list, "today");//通过反射添加
		for(Object obj: list){
			System.out.println(obj);
		}

4.泛型限定

   (1).通配符<?>,也可以理解为占位符

       ?通配符只能调用与参数化无关的方法,不能调用与参数化有关的方法

   (2).上限:<? extends E>,可以接收E类型或者是E类型的子类
		List<Integer> x;
		List<? extends Number> y;
		y = x;	//true Integer 继承了Number
		x = y;	//false 应注意这种区别

   (3).下限:<? super E>,可以接受E类型或者E的父类型,通常用的不多.

5.得到集合泛型类型

//得到集合的泛型类型
public class Test {
	public static void main(String[] args) throws Exception{
		Method m = Test.class.getMethod("app", ArrayList.class);//对象下面的app函数
		Type[] types = m.getGenericParameterTypes();			//可能会接收多个泛型
		ParameterizedType pType = (ParameterizedType)types[0];
		System.out.println(pType.getRawType());					//class java.util.ArrayList
		System.out.println(pType.getActualTypeArguments()[0]);	//数组    class cn.Person
	}
	public static void app(ArrayList<Integer> a) {
	}
}


6.自定义泛型方法细节

7.泛型的代码实现

   (1).自定义泛型和静态方法

import java.util.*;
class Person<T>		//泛型类
{
	private T var;
	public void set(T var)
	{
		this.var = var;
	}
	public T get()
	{
		return var;
	}
//	public static void method();		//静态方法不可以访问类上定义的泛型,static方法属于类
	public static <T> void method();	//可以将泛型定义在static方法上。
}

class GenericDemo
{
	public static void main(String[] args)
	{
		Person<String> p1 = new Person<String>();
		p1.set("name");					//Person<String>定义与类Person一一对应(Person<T>)!

		Person<Integer> p2 = new Person<Integer>();
		p2.set(12);

		System.out.println(p1.get());
		System.out.println(p2.get());
	}
}

   (2).自定义泛型方法

//泛型方法Strawberry2013-4-29
import java.util.*;
class Demo
{
	public <T> void show(T t)	//泛型位置处在 返回值的前面,修饰符的后面!
	{
		System.out.println(t);
	}
}

class GenericDemo
{
	public static void main(String[] args)
	{
		Demo d = new Demo();
		d.show("hhe");
		d.show(3);
	}
}

   (3).自定义泛型接口

import java.util.*;
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()) ;  
    }  
}

   (4).通配符<?>

//?通配符,也可以理解为占位符
import java.util.*;
class Demo<T>
{
	private T t;
	public void set(T t)
	{
		this.t = t;
	}
	public T get()
	{
		return t;
	}
}

class GenericDemo
{
	public static void main(String[] args)
	{
		Demo<String> d1 = new Demo<String>();
		d1.set("haha");

		Demo<Integer> d2 = new Demo<Integer>();
		d2.set(123);

		method(d1);
		method(d2);
	}
	public static void method(Demo<?> d) //Demo<?>任意类型的
	{
		System.out.println(d.get());
	}
}

   (5).<? extends E>

import java.util.*;
class Person
{
	private int age;
	Person(int age)
	{
		this.age = age;
	}
	public int getAge()
	{
		return age;
	}
}

class Student extends Person
{
	Student(int age)
	{
		super(age);
	}
}
class Worker extends Person
{
	Worker(int age)
	{
		super(age);
	}
}

class GenericDemo
{
	public static void main(String[] args)
	{
		TreeSet<Student> ts1 = new TreeSet<Student>(new Comp());
		ts1.add(new Student(20));			//TreeSet<E>(Comparator<? super E> comparator)
		ts1.add(new Student(10));
		ts1.add(new Student(30));

		TreeSet<Worker> ts2 = new TreeSet<Worker>(new Comp());
		ts2.add(new Worker(12));
		ts2.add(new Worker(32));
		ts2.add(new Worker(22));

		method(ts1);
		method(ts2);
	}
	public static void method(TreeSet<? extends Person> d) 
	{
		Iterator<? extends Person> it = d.iterator();
		while(it.hasNext())
		{
			System.out.println(it.next().getAge());
		}
	}
}

class Comp implements Comparator<Person>	//TreeSet(Comparator<? super E> comparator) 
{											//E的父类 <? super E>
	public int compare(Person p1, Person p2)//Person p = new Student(12);
	{
		return p1.getAge() - p2.getAge();	//只能使用父类的方法
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值