Java中泛型的各种使用

Java中的泛型的使用:

1.普通的泛型使用

在使用类的时候后面的<>中的类型就是我们确定的类型。

public class MyClass1<T> {//此处定义的泛型是T
    private T var;

    public T getVar() {
        return var;
    }

    public void setVar(T var) {
        this.var = var;
    }
}
/**
 * 最普通的泛型使用,只有一个泛型类型
 */
@Test
public void testMyClass1() {
    MyClass1<String> clazz = new MyClass1<String>();//此事确定对象对应的泛型T是String
    clazz.setVar("stringType");
    String str = clazz.getVar();
    System.out.println(str);
}

2.带有两个泛型类型

和普通的泛型使用基本一样,只是我们可以在使用类的时候定义两个不同的泛型类型,当然我们也可以定义多个,只要我们业务需要。

public class MyClass2<K, V> {//此处定义两个泛型类型
    private K var1;//第一个变量的类型是K对应的具体类型
    private V var2;//第二个变量的类型是V对应的具体类型

    public K getVar1() {
        return var1;
    }

    public void setVar1(K var1) {
        this.var1 = var1;
    }

    public V getVar2() {
        return var2;
    }

    public void setVar2(V var2) {
        this.var2 = var2;
    }

}

/**
 * 含有两个泛型类型的使用
 */
@Test
public void testMyClass2() {
    //此处确定定义的clazz对象的第一个泛型类型是Integer,第二个泛型类型是String
    MyClass2<Integer, String> clazz = new MyClass2<Integer, String>();
    clazz.setVar1(1); //此处只能用int类型的参数
    clazz.setVar2("string");//此处只能用String类型的参数

    System.out.println(clazz.getVar1() + "," + clazz.getVar2());
}

3.含有通配符的泛型

这里面又包含3种:没限制的通配符、使用extends限制、使用super限制

public class MyClass3<T> {
    private T var;

    public T getVar() {
        return var;
    }

    public void setVar(T var) {
        this.var = var;
    }

    @Override
    public String toString() {
        return var.toString();
    }

}
/**
 * 通配符?的使用 包括<?>、<?extends 类型>和<? super 类型>
 */
@Test
public void testMyClass3() {
    MyClass3<Boolean> clazz = new MyClass3<Boolean>();
    clazz.setVar(false);
    fun(clazz);//调运该方法的时候,对泛型没有限制,任何类型的泛型都可以使用

    MyClass3<Integer> clazzInt = new MyClass3<Integer>();
    clazzInt.setVar(1);
    funExtends(clazzInt);//调运该方法的时候,只能使用Number类型或者其子类型

    MyClass3<Double> clazzDouble = new MyClass3<Double>();
    clazzDouble.setVar(2.2);
    funExtends(clazzDouble);//调运该方法的时候,只能使用Number类型或者其子类型

    MyClass3<String> clazzString = new MyClass3<String>();
    clazzString.setVar("string");
    funSuper(clazzString);//调运该方法的时候,只能使用String类型或者其父类型

    MyClass3<Object> clazzObject = new MyClass3<Object>();
    clazzObject.setVar(new Object());
    funSuper(clazzObject);//调运该方法的时候,只能使用String类型或者其父类型

}

public void fun(MyClass3<?> clazz) {//没有限制的泛型使用
    System.out.println(clazz);
}

public void funExtends(MyClass3<? extends Number> clazz) {//只能使用Number及其子类的泛型
    System.out.println(clazz);
}

public void funSuper(MyClass3<? super String> clazz) {//只能使用String及其父类的泛型
    System.out.println(clazz);
}

4.定义类的时候就对泛型进行限制

public class MyClass4<T extends Number> {//定义类的泛型的时候进行泛型的限制
    private T var;

    public T getVar() {
        return var;
    }

    public void setVar(T var) {
        this.var = var;
    }

    @Override
    public String toString() {
        return this.var.toString();
    }

}

/**
 * 定义类的泛型的时候都给定泛型的限制
 */
@Test
public void testMyClass4() {
    //同样只能定义Number及其子类的泛型
    // MyClass4<String> clazzString = new MyClass4<String>();
    MyClass4<Integer> clazzInt = new MyClass4<Integer>();
    MyClass4<Double> clazzDouble = new MyClass4<Double>();

    MyClass4<Float> clazzFClass4 = fun(1.1f);
    //此处调运的参数是float类型,这就确定了返回类型必须是float
}

public <T extends Number> MyClass4<T> fun(T arg) {
    return new MyClass4<T>();

}

5.泛型接口的使用

public interface MyInterface<T> {
    public T getVar();
}

//两种实现方式。1,在实现的时候还是使用泛型,到具体定义对象的时候再确定
public class MyInterface1Impl<T> implements MyInterface<T> {
    private T var;

    public MyInterface1Impl() {
    }

    public MyInterface1Impl(T var) {
        this.var = var;
    }

    @Override
    public T getVar() {
        return this.var;
    }

}
//第二种实现方式,在实现的时候就确定泛型的类型
public class MyInterface2Impl implements MyInterface<String> {
    private String varStr;

    public MyInterface2Impl() {
    }

    public MyInterface2Impl(String varStr) {
        this.varStr = varStr;
    }

    @Override
    public String getVar() {
        return this.varStr;
    }
}

/**
 * 泛型接口的使用
 */
@Test
public void testMyInterface() {
    //实现类可以定义为任意类型的泛型
    MyInterface1Impl<String> varStr = new MyInterface1Impl<String>("abc");
    System.out.println(varStr.getVar());
    MyInterface1Impl<Integer> varInt = new MyInterface1Impl<Integer>(123);
    System.out.println(varInt.getVar());

    //之前已经在类实现的时候已经确定了只能是String
    MyInterface2Impl var = new MyInterface2Impl("cba");
    String str = var.getVar();
    System.out.println(str);
}

6.泛型方法的使用

public class MyFunction {
    public <T> T fun1(T arg) {//传入参数和返回参数都是同样的泛型类型
        return arg;
    }

    public <T> void fun2(T arg) {//传入参数是泛型,不需要返回
        if (arg instanceof String) {
            System.out.println("T is StringType");
        } else if (arg instanceof Integer) {
            System.out.println("T is IntegerType");
        } else {
            System.out.println("T is OtherType");
        }
    }

    public <T> String fun3(T arg) {//传入的参数是泛型,返回的确定类型
        return arg.toString();
    }
}

/**
 * 泛型方法的使用
 */
@Test
public void MyFunction() {
    MyFunction clazz = new MyFunction();

    //传入什么类型,返回什么类型
    String var1 = clazz.fun1("abc");
    int var2 = clazz.fun1(12);
    System.out.println(var1);
    System.out.println(var2);

    //无论传入的是什么类型,都没关系
    clazz.fun2(1);
    clazz.fun2(false);
    clazz.fun2("string");

    //无论传入什么,都返回的是String
    String var3 = clazz.fun3(123);
    String var4 = clazz.fun3("string");
    System.out.println(var3);
    System.out.println(var4);

}

7.泛型数组

/**
 * 泛型数组的使用
 */
@Test
public void testArray(){
    Integer[] arr = fun(1,2,3);

}

public <T> T[] fun(T... args){//传入什么类型,T就是什么类型,并且可以使用泛型遍历
    for(T t:args){
        System.out.println(t.toString());
    }
    return args;
}

8.嵌套泛型

/**
 * 嵌套泛型
 */
@Test
public void testNest(){
    //外层泛型的类型其实就是内层泛型,当内层泛型确定了,那外层泛型也就确定了
    MyClass1<MyClass2<Integer, String>> nestOut = new MyClass1<MyClass2<Integer,String>>();
    MyClass2<Integer, String> nestIn = new MyClass2<Integer,String>();
    nestIn.setVar1(1);
    nestIn.setVar2("a");
    nestOut.setVar(nestIn);
    System.out.println(nestOut.getVar().getVar1());
    System.out.println(nestOut.getVar().getVar2());
}
时间: 2024-11-07 04:50:04

Java中泛型的各种使用的相关文章

Java 中 泛型的限定

泛型 一般 出现在集合中,迭代器中 也会出现! 泛型 是为了 提高代码的 安全性. 泛型 确保数据类型的唯一性. 在我们常用的容器中,  越是 单一 约好处理啊! 泛型的限定: ? 是通配符 指代 任意类型 泛型的限定上限: <? extends E> 接受 E 或者 E 的子类型. 泛型的限定下限: <?  super   E>  接收  E 或者 E 的父类. 泛型的限定上限 (定义父类 填装子类 类型!) 代码: package stu.love.v; import java

Java中泛型 使用

泛型: 1.5  之后出现  提高安全 1      泛型 确定 集合容器的类型. 2      <> 接收一种数据类型,(引用数据类型) ArrayList<String> lis = new ArrayList<String>() 目的: 将运行时期的 错误 转化到 编译时期,提高了安全性! 3      不需要 强制类型转换.  更加安全! 泛型的 擦除: 泛型在编译时期使用!使用完毕直接擦除. 编译完的时候 不存在 泛型. 好处: 使用了 泛型,不自需要强制类型

Java中泛型 类型擦除

转自:Java中泛型是类型擦除的 Java 泛型(Generic)的引入加强了参数类型的安全性,减少了类型的转换,但有一点需要注意:Java 的泛型在编译器有效,在运行期被删除,也就是说所有泛型参数类型在编译后都会被清除掉,看下面一个列子,代码如下: public class Foo { public void listMethod(List<String> stringList){ } public void listMethod(List<Integer> intList) {

java中泛型上限,下限应用

import java.util.*; class Person implements Comparable<Person>{ String name; int age; Person(){ name = ""; age = 0; } Person(String name, int age){ this.name = name; this.age = age; } public String toString(){ return name + "...."

Java中泛型的协变

在工作中遇到一个问题,用代码描述如下: package test; import java.util.LinkedList; import java.util.List; public class ListTest {     public void func(List<Base> list) {     }     public static void main(String args[]) {         ListTest lt = new ListTest();         Li

Java 中泛型的全面解析

Java泛型(generics) 是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter).声明的类型参数在使用时用具体的类型来替换.泛型最主要的应用是在JDK 5中的新集合类框架中.对于泛型概念的引入,开发社区的观点是褒贬不一.从好的方面来说,泛型的引入可以解决之前的集合类框架在使用过程中通常会出现的运行时刻类型错误,因为编译器可以在编译时刻就发现很多明显的错误.而从不好的地方来说,为了保证与旧有版本的兼容性,Java泛型的实现上存在着一些不够优雅的

Java中泛型在集合框架中的应用

泛型是Java中的一个重要概念,上一篇文章我们说过,当元素存入集合时,集合会将元素转换为Object类型存储,当取出时也是按照Object取出的,所以用get方法取出时,我们会进行强制类型转换,并且通过代码也可以看出来,我们放入其他类型时,如字符串,编译器不会报错,但是运行程序时会抛出类型错误异常,这样给开发带来很多不方便,用泛型就解决了这个麻烦 泛型规定了某个集合只能存放特定类型的属性,当添加类型与规定不一致时,编译器会直接报错,可以清楚的看到错误 当我们从List中取出元素时直接取出即可,不

Java中泛型的介绍与简单使用

学习目标 掌握泛型的产生意义. 掌握泛型的基本使用. 了解泛型的警告信息及泛型的擦除. 泛型是在JDK1.5之后增加的内容,泛型(Generic) 使用泛型的原因 题目分析: 首先要考虑到,必须建立一好一个表示坐标点的类--Point,此类中有两个属性分别用来表示x坐标和y坐标,但是x和y中所保存的整数类型会有三种(int.float.String),而要想使用一个类型可以同时接收这样的三种类型数据,现在只能使用Object,因为Object类可以接收任何类型的数据,都会自动发生向上转型操作,这

Java中泛型的理解

Java中的泛型,本质上来说,就是是参数化类型,就是说所操作的数据类型被指定为一个参数,而不是确定的某种类型.这种数据类型可以用在类.接口和方法创建中.即泛型类.泛型接口.泛型方法.这样说可能不够生动,来举些例子说明一下. 例子一 我们通过 例子一 来简单看看泛型的应用场景.下面的情况中,没有使用泛型: public class FanXingTest { public static void main(String[] args) { ArrayList arrayList = new Arr

Java中泛型数组创建总结

在java中,可以声明一个泛型数组,不能通过直接通过T[] tarr=new T[10]的方式来创建数组,最简单的方式便是通过Array.newInstance(Classtype,int size)的方式来创建数组例如下面的程序. public class ArrayMaker<T> { private Class<T> type; public ArrayMaker(Class<T> type) { this.type = type; } @SuppressWarn