java泛型

泛型
泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数类型。

泛型类

定义泛型类在"类名"后添加一对<>,里面定义"泛型名称";
格式:如ArrayList集合

class ArrayList< E > {
     public boolean add(E e) { }
     public E get(int index) { }
}

使用泛型类:创建对象时,确定泛型的类型
例如:ArrayList< String > list = new ArrayList< String >(); 此时相当于将E的类型替换为String类型。
例如:ArrayList< Integer > list = new ArrayList< Integer >(); 此时相当于将E的类型替换为Integer类型。

/*
   泛型类定义格式
             格式:修饰符 class 类名<类型> {}
             范例:public class Generic<T>{}
                  此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
 */
public class Test {
    public static void main(String[] args) {
        Student s = new Student();
        s.setName("张三");
        System.out.println(s.getName());
        Teacher t = new Teacher();
        t.setAge(30);
//        t.setAge("30");
        System.out.println(t.getAge());

        System.out.println("--------------");

        Generic<String>g1=new Generic<String>();
        g1.setT("张三");
        System.out.println(g1.getT());
        Generic<Integer>g2=new Generic<Integer>();
        g2.setT(18);
        System.out.println(g2.getT());

    }
}

class Student {
    private String name;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

class Teacher {
    private Integer age;

    public Teacher() {
    }

    public Teacher(Integer age) {
        this.age = age;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
class Generic<T>{
    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}

结果:

张三
30
--------------
赵四
18
泛型方法
方法格式:
/**
	 * <T> 声明此方法持有一个类型T,也可以理解此方法为泛型方法
	 * T 返回值类型(入参类型是什么类型此返回值就是什么类型)
	 * @param t1 泛型参数
	 * @param t2 泛型参数
	 */
	public static <T> T m1(T t1) {
		return t1;
	}
详细介绍
/**
 * 泛型方法的详细介绍
 * @param value 传入的泛型实参
 * @return T 返回值为T类型
 * 说明:
 *     1. public 与 返回值中间<T>非常重要,可以理解为声明此方法为泛型方法。
 *     2. 只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
 *     3. <T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
 *     4. 与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。
 */
public <T> T genericMethod(T value)throws InstantiationException ,
        IllegalAccessException{
    return value;
}

示例:

/*
    泛型方法定义格式:
           格式:修饰符 <类型> 返回值类型 方法名(类型 变量名){}
           范例:public <T> void show(T t){}
 */
public class Test {
    public static void main(String[] args) {
        //        Generic g = new Generic();
//        g.show("张三");
//        g.show(18);
//        g.show(true);
//        g.show(13.14);

//        Generic<String> g1 = new Generic<String>();
//        g1.show("赵四");
//        Generic<Integer> g2 = new Generic<Integer>();
//        g2.show(18);
//        Generic<Boolean> g3 = new Generic<Boolean>();
//        g3.show(true);

        Generic g=new Generic();
        g.show("张三");//String
        g.show(18);//int
        g.show(true);//boolean
        g.show(13.14);//double

    }
}

//class Generic {
//    public void show(String s) {
//        System.out.println(s);
//    }
//
//    public void show(Integer i) {
//        System.out.println(i);
//    }
//
//    public void show(Boolean b) {
//        System.out.println(b);
//    }
//}

//泛型类改进
//class Generic<T> {
//    public void show(T t) {
//        System.out.println(t);
//    }
//}

//泛型方法改进
class Generic {
    public <T> void show(T t) {
        System.out.println(t);
    }
}

结果:

张三
18
true
13.14
泛型接口
接口格式

泛型不仅可以声明泛型类,也可以声明泛型接口,声明泛型接口和声明泛型类的语法相似,也是在接口名称后面加< T >

格式:权限修饰符 interface 接口名<泛型标示符>{}

/*
    泛型接口定义格式:
         格式:修饰符 interface 接口名<类型>{}
         范例:public interface Generic<T>{}
 */
public class Test {
    public static void main(String[] args) {
        Generic<String> g1 = new GenericTmpl<String>();
        g1.show("张三");
        Generic<Integer> g2 = new GenericTmpl<Integer>();
        g2.show(18);
        Generic<Boolean> g3 = new GenericTmpl<Boolean>();
        g3.show(true);

    }
}

interface Generic<T> {
    public void show(T t);
}

class GenericTmpl<T> implements Generic<T> {
    @Override
    public void show(T t) {
        System.out.println(t);
    }
}
泛型接口实现方式

方式一:

子类继续定义泛型类型,通过使用者来确定具体类型
然后使用泛型接口

public class Test {
    public static void main(String[] args) {
        Fan<String> i = null; // 声明接口对象
        i = new Zi<String>("李四"); // 通过子类实例化对象
        System.out.println("内容:" + i.getVal());
    }

}

interface Fan<T> { // 在接口上定义泛型
    public T getVal(); // 定义抽象方法,抽象方法的返回值就是泛型类型
}

//子类继续定义泛型类型,有使用者来确定
class Zi<T> implements Fan<T> { // 定义泛型接口的子类
    private T val; // 定义属性

    public Zi(T val) { // 通过构造方法设置属性内容
        this.setVal(val);
    }

    public void setVal(T val) {//通过方法参数确定
        this.val = val;
    }

    public T getVal() {
        return this.val;
    }
}

方式二:

子类确定泛型类型

interface Info<T> { // 在接口上定义泛型
	public T getVar(); // 定义抽象方法,抽象方法的返回值就是泛型类型
}
class InfoImpl implements Info<String> { // 子类确定泛型类型
	@Override
	public String getVar() {//因为在类里面已经确定了泛型类型,所以约束了方法的泛型
		return null;
	}
}
泛型通配符

类型通配符一般是使用?代替具体的类型参数
例如 List<?> 在逻辑上是List< String >,List< Integer > 等所有List<具体类型实参>的类

通配符的使用

public void show( List < ? > list ){ }:表示可以接收具有"任何泛型"的"List类型"的集合

泛型上限指定

< ? extends E >:只能指向具有E,或者其子类的泛型的对象
public void show( List < ? extends Student > list ){ }:表示只能接收具有"Student"或者"其子类"泛型的集合对象;
泛型下限指定
< ? super E >:只能指向具有E,或者其父类的泛型的对象
还可以看到
public void show( List < ? super Student > stuList ){ } :表示只能接受Student类和其父类的集合对象

public class Test {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<Student>();
        List<Teacher> teachers = new ArrayList<Teacher>();
        List<Person> persons = new ArrayList<Person>();
        List<String> strings = new ArrayList<String>();

        // 可以调用
        m1(strings);
        m1(strings);

        // 因为m2()方法中的参数已经限定了参数泛型上限为Person,
        // String类型不在这个范围之内,所以会报错
        // m2(strings);

        // 类型通配符下限通过形如 List<? super Student>来定义,
        // 表示类型只能接受Student及其三层父类类型,如Objec类型的实例。
        //m3(teachers);
        m3(persons);// 可以通过
    }

    public static void m1(List<?> data) {
    }

    public static void m2(List<? extends Person> data) {
    }

    public static void m3(List<? super Student> stuList) {
    }

    class Person {
    }

    class Student extends Person {
    }

    class Teacher extends Person {
    }
}
泛型好处

可以消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的键或值保存在集合中。这就是泛型所做的工作。

1.类型安全
2.消除强制类型转换

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值