目录
一、简介
1.泛型是JDK1.5引入的新特性,也是最重要的一个特性
2.泛型可以在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的
3.泛型的原理就是“类型的参数化”,即把类型看做参数。也就是说把所要操作的数据类型看做参数,就像方法的形式参数是运行时传递的值的占位符一样
4.简单的说,类型变量扮演的角色就如同一个参数,它提供给编译器用来类型检查的信息。
5.泛型可以提高代码的扩展性和重用性
总结:所谓泛型,即通过数化类型来实现在同一份代码上操作多种数据类型,泛型编程是一种编程范式,它利用"参数化类型" 将类型抽象化,从而实现更为灵活的复用。
二、泛型类
1、泛型的类型参数可以是泛型类
2、泛型类可以同时设置多个类型参数
3、泛型类可以继承泛型类
4、泛型类可以实现泛型接口
public class GenericDemo1 {
public static void main(String[] args) {
/*创建泛型类对象*/
GenClass<String> genClass1 = new GenClass<String>("张三");
System.out.println(genClass1.getData());
GenClass<Integer> genClass2 = new GenClass<Integer>(20);
System.out.println(genClass2.getData());
System.out.println("----------------------");
/*型的类型参数可以是泛型类*/
GenClass<Student> genClass4 = new GenClass<Student>(new Student("李四"));
GenClass<GenClass<Student>> genClass3 = new GenClass<GenClass<Student>>(genClass4);
System.out.println(genClass3.getData().getData());
System.out.println("----------------------");
/*泛型类可以同时设置多个类型参数*/
GenClass1<String, Integer> genClass5 = new GenClass1<String, Integer>("李四", 20);
System.out.println(genClass5.getData1()+"--"+genClass5.getData2());
System.out.println("----------------------");
/*泛型类可以继承泛型类*/
SonClass<String,Integer> genClass6 = new SonClass<String,Integer>("王五",24);
System.out.println(genClass6.show());
System.out.println("----------------------");
/*泛型类可以实现泛型接口*/
genClass6.show2();
}
}
/*创建泛型类*/
class GenClass<T>{
private T data;
public GenClass(T data){
this.data = data;
}
public void setData(T data){
this.data = data;
}
public T getData(){
return data;
}
}
class Student{
private String name;
public Student(String name){
this.name = name;
}
public String toString(){
return "我是:"+name;
}
}
class GenClass1<T1,T2>{
private T1 data1;
private T2 data2;
public GenClass1(T1 data1,T2 data2){
this.data1 = data1;
this.data2 = data2;
}
public void setData(T1 data1,T2 data2){
this.data1 = data1;
}
public void setData(T2 data2){
this.data2 = data2;
}
public T1 getData1(){
return data1;
}
public T2 getData2(){
return data2;
}
}
class SuperClass<T1>{
private T1 data1;
public SuperClass(T1 data1){
this.data1 = data1;
}
public T1 show(){
return data1;
}
}
interface IInter<T2>{
public void show2();
}
class SonClass<T1,T2> extends SuperClass<T1> implements IInter<T2>{
private T2 data2;
public SonClass(T1 data1,T2 data2){
super(data1);
this.data2 = data2;
}
public T1 show(){
return super.show();
}
@Override
public void show2() {
System.out.println(data2);
}
}
三、限制泛型可用类型
在定义泛型类别时,默认在实例化泛型类的时候可以使用任何类型,但是如果想要限制使用泛型类型时,只能用某个特定类型或者是其子类型才能实例化该类型 时,可以在定义类型时,使用extends关键字指定这个类型必须是继承某个类,或者实现某个接口
当没有指定泛型继承的类型或接口时,默认使用extendsObject,所以默认情况下任何类型都可以做为参数传入
public class GenericDemo3 {
public static void main(String[] args) {
GenericClass<Dog> dogclass = new GenericClass<Dog>();
dogclass.setObj(new Dog());
dogclass.getObj().eat();
GenericClass<Cat> catclass = new GenericClass<Cat>();
catclass.setObj(new Cat());
catclass.getObj().eat();
/*GenericClass<String> str = new GenericClass<String>();*/
}
}
/*泛型所接受的参数做了限制,只能接受Animall类型或Animall子类*/
class GenericClass<T extends Animal1>{
private T obj;
public void setObj(T obj){
this.obj = obj;
}
public T getObj(){
return obj;
}
}
abstract class Animal1{
public abstract void eat();
}
class Dog extends Animal1{
@Override
public void eat() {
System.out.println("狗啃骨头");
}
}
class Cat extends Animal1{
@Override
public void eat() {
System.out.println("鱼吃鱼头");
}
}
四、类型通配声明
同一泛型类,如果实例化时给定的实际类型不同,则这些 实例的类型是不兼容的,不能相互赋值。
Generic<Boolean> f1= new Generic<Boolean>();
Generic<Integer> f1= new Generic<Integer>();
f1= f2;/*发生编译错误*/
Generic<Object> f = f1;/*f1和f类型并不兼容,发生编译错误*/
f = f2;/*f2和f类型同样不兼容,发生编译错误*/
泛型类实例之间的不兼容性会带来使用的不便。我们可以使用泛型通配符(?)声明泛型类的变量就可以解决这个问题。
泛型通配符的方式
“?”代表任意一个类型
GenericClass<Boolean> f1 = new GenericClass<Boolean>();
GenericClass<?> f = f1;
和限制泛型的上限相似,同样可以使用extends关键字限定通配符匹配类型的上限
GenericClass<Dog> f1 = new GenericClass<Dog>();
GenericClass<? extends Animal1> f = f1;
可以使用super关键词将通配符匹配类型限定为某个类型及其父
GenericClass<Animal1> f1 = new GenericClass<Animal1>();
GenericClass<? super Dog> f = f1;
五、泛型方法
不仅类可以声明泛型,类中的方法也可以声明仅用于自身的泛型,这种方法叫做泛型方法。其定义格式为:
访问修饰符 <泛型列表> 返回类型 方法名(参数列表){
实现代码
}
在泛型列表中声明的泛型,可用于该方法的返回类型声明、参数类型声明和方法代码中的局部变量的类型声明。
类中其他方法不能使用当前方法声明的泛型。
提示:是否拥有泛型方法。与其所在的类是否泛型没有关系。
要定义泛型方法,只需将泛型参数列表置于返回值前。
泛型方式的使用场所
1.添加类型约束只作用于一个方法的多个参数之间、而不涉及到类中的其他方法时。
2.施加类型约束的方法为静态方法,只能将其定义为泛型方法,因为静态方法不能使用其所在类的类型参数。
public class GenericDemo3 {
public static void main(String[] args) {
GenericClass genericClass = new GenericClass();
genericClass.printIn("张三");
genericClass.printIn(20);
genericClass.printIn(new Dog());
}
}
class GenericClass{
/*泛型方法*/
public <T> void printIn(T content){
System.out.println(content);
}
/*方法重载*/
public <T extends Animal1> void printIn(T animal1){
animal1.eat();
}
}
abstract class Animal1{
public abstract void eat();
}
class Dog extends Animal1{
@Override
public void eat() {
System.out.println("狗啃骨头");
}
}