Java泛型基础

Java基础

浏览数:99

2019-2-23

Java泛型基础

1. 认识泛型

  • 泛型是在JDK1.5之后增加的新功能.
  • 泛型可以解决数据的安全性问题, 主要的原理是在类声明的时候通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型.
  • 格式:
访问权限 class 类名称<泛型, 泛型...>{
    属性
    方法
}
  • 对象的创建:
    类名称<具体类型> 对象名称 = new 类名称<具体类型>();

  • 示例

/**
 * 经纬度
 * 
 * @author dixin
 *
 */
class Point<T> {
    private T x;
    private T y;

    public T getX() {
        return x;
    }

    public void setX(T x) {
        this.x = x;
    }

    public T getY() {
        return y;
    }

    public void setY(T y) {
        this.y = y;
    }
}

public class GenericDemo01 {

    public static void main(String[] args) {

        Point<String> p1 = new Point<String>();
        p1.setX("经度为10");
        p1.setY("纬度为100");

        Point<Integer> p2 = new Point<Integer>();
        p2.setX(10);
        p2.setY(100);

        System.out.println(p1.getX() + ", " + p1.getY());
        System.out.println(p2.getX() + ", " + p2.getY());
    }
}

// 执行结果
经度为10, 纬度为100
10, 100

2. 构造方法中使用泛型

class Con<T> {

    private T value;
    // 类定义中已经定义泛型T, 方法中可以直接使用, 不用加<>
    public Con(T value) {
        this.value = value;
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }
}

public class GenericDemo02 {

    public static void main(String[] args) {
        Con<String> c = new Con<String>("构造方法中使用泛型");
        System.out.println(c.getValue());
    }
}

3. 设置多个泛型

  • 两个泛型的例子:
class Gen<K, T> {

    private K key;
    private T value;

    public K getKey() {
        return key;
    }

    public void setKey(K key) {
        this.key = key;
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }

}

public class GenericDemo03 {

    public static void main(String[] args) {
        Gen<String, Integer> gen = new Gen<String, Integer>();
        gen.setKey("key");
        gen.setValue(10);

        System.out.println(gen.getKey() + ", " + gen.getValue());
    }
}

4. 通配符

  • 类型不统一问题
class Info<T> {

    private T value;

    public void setValue(T value) {
        this.value = value;
    }

    public T getValue() {
        return value;
    }

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

public class GenericDemo04 {

    public static void main(String[] args) {
        Info<String> i = new Info<String>();
        i.setValue("类型不统一");
        tell(i); // 编译报错
        // The method tell(Info<Object>) in the type GenericDemo04 is not applicable for the arguments 
 (Info<String>)
    }

    public static void tell(Info<Object> i) {
        System.out.println(i);
    }
}

原因:
泛型是不可变的, 对于任意两个不同的类型Type1和Type2, List<Type1>既不是List<Type2>的子类型, 也不是List<Type2>的父类型. 所以这里不能将<String>转换成<Object>.

解决方式:

  • public static void tell(Info<Object> i)中去掉<Object>, 使用raw类型, 但这样就失去了泛型的安全性检查意义.
  • 更好的方式, 采用通配符.
    修改为public static void tell(Info<?> i)

5. 泛型接口

  • 声明泛型接口和声明泛型类的语法类似, 也是在接口名称后面加上<T>.

  • 格式:
    interface 接口名称<泛型标识>

  • 示例:

interface IGen<T> {
    public void say();
}

class GenImpl<T> implements IGen<T> {

    private String info;

    public GenImpl(String info) {
        this.info = info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public String getInfo() {
        return info;
    }

    @Override
    public void say() {
        System.out.println(this.info);
    }
}

public class GenericDemo05 {

    public static void main(String[] args) {
        IGen<String> g = new GenImpl<String>("泛型接口");
        g.say();
    }
}

6. 泛型方法

  • 泛型方法中可以定义泛型参数, 此时, 参数的类型就是传入数据类型.
  • 格式:
    访问权限 <泛型标识> 泛型标识 方法名称([泛型标识 参数名称])
  • 示例:
public class GenericDemo06 {

    public static void main(String[] args) {
        String str = tell("Hello");
        System.out.println(str);
        int i = tell(10);
        System.out.println(i);
    }
    
    // <T>是第一泛型参数, 写在访问权限和static后面
    public static <T> T tell(T t) {
        return t;
    }
}

// 执行结果
Hello
10

7. 泛型数组

泛型数组的使用要和泛型方法搭配使用.

  • 在使用泛型方法的时候, 也可以传递或返回一个泛型数组.
public class GenericDemo07 {

    public static void main(String[] args) {

        String arrStr[] = { "A", "B", "C" };
        tell(arrStr);

        Integer arrInt[] = { 1, 2, 3 };
        tell(arrInt);
    }

    public static <T> void tell(T arr[]) {
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}