java—泛型

本文详细介绍了Java中的泛型,包括泛型的基本概念、泛型类的定义与使用、泛型方法的声明与调用、泛型方法与泛型类的关系、通配符的应用以及泛型接口的实现。泛型允许在类和方法中延迟指定数据类型,提高了代码的复用性和安全性。通过泛型上限和下限,可以灵活控制参数类型。

(一)泛型的基本概念

  • 泛型指的就是在类定义的时候并不会设置类中的属性或方法中的参数的具体类型,而是在类使用时再进行定义。
    如果要想进行这种泛型的操作,就必须做一个类型标记的声明。
  • 泛型只能接受类,所有的基本数据类型必须使用包装类

(二)泛型类

  • 泛型类的基本语法:
    class MyClass< T > {
    T value1;
    }

    注意事项:
    (1)尖括号 <> 中的 T 被称作是类型参数,用于指代任何类型。实际上这个T你可以任意写,但出于规范的目的,Java还是建议我们用单个大写字母来代表类型参数。
    (2)如果一个类被 的形式定义,那么它就被称为是泛型类。
    (3)在定义类的时候,只指定类的泛型参数,只有在使用泛型类的时候,才会制定具体的参数类型。
    (4)泛型类可以有多个参数。
  • 泛型类的使用:
    假设需要你定义一个描述坐标的程序类Point,需要提供两个属性x、y。对于这两个属性的内容可能有如下选择:int型,double型,字符串型。
    在定义类的时候无法确定具体的使用类型,因此此时使用泛型类。
    举例1:
package www.fanfan.com;

import www.fanfan.com.Point;

//1. 使用泛型类,指定参数类型
//泛型类中属性的类型与普通方法的参数类型可以与类中制定的参数类型一样
public class Point2<T> {
    private T x;
    private T y;

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

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

    public T getX() {
        return x;
    }

    public T getY() {
        return y;
    }

    @Override
    public String toString() {
        return "Point2{" +
                "x=" + x +
                ", y=" + y +
                '}';
    }

    public static void main(String[] args) {
    //使用泛型类时指定具体的参数类型
        Point2<Integer> integerPoint2 = new Point2<>();
        integerPoint2.setX(1);
        integerPoint2.setY(2);
        System.out.println(integerPoint2);

        Point2<String> stringPoint2 = new Point2<>();
        stringPoint2.setY("东京180°");
        stringPoint2.setX("北纬30°");
        System.out.println(stringPoint2);
    }
}

在这里插入图片描述

(三)泛型方法

  1. 泛型方法与泛型类没有关系;
  2. 泛型方法的定义:
    class MyClass{
    public < T> void testMethod(T t) {
    System.out.println(t);
    }
    }
  3. 泛型方法与泛型类稍有不同的地方是,类型参数也就是尖括号那一部分是写在返回值前面的。 中的 T 被称为类型参数,而方法中的 T 被称为参数化类型,它不是运行时真正的参数。
  4. 声明的类型参数,其实也是可以当作返回值的类型的。
    举例2:
    泛型方法的使用:
package www.fanfan.com;
//泛型方法
public class Point4 {
    public <T> void print(T o){
        System.out.println(o);
    }
    public static void main(String[] args) {
        Point4 point4 = new Point4();
        point4.print(3);
        point4.print("hello");
    }
}

(四)泛型方法与泛型类

  1. 泛型方法与泛型类可以共存,两者各自独立;
  2. 泛型类和泛型方法 类型参数使用的字母最好区别开。
    举例3:
package www.fanfan.com;

import org.omg.Messaging.SYNC_WITH_TRANSPORT;

//泛型类与泛型方法可以共存
public class Point5<T,E>{
    private T x;
    private E y;

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

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

    public T getX() {
        return x;
    }

    public E getY() {
        return y;
    }

    @Override
    public String toString() {
        return "Point5{" +
                "x=" + x +
                ", y=" + y +
                '}';
    }
    //这是泛型类中的一个普通方法
    //普通方法中类型参数与类名中的类型参数一致
    public void test(T t){
        System.out.println(t);
    }
    //泛型方法
    public <X> void print(X o){
        System.out.println(o);
    }

    public static void main(String[] args) {
        Point5<Integer,Integer> integerIntegerPoint5 = new
                Point5<>();
        integerIntegerPoint5.setX(89);
        integerIntegerPoint5.setY(90);
        System.out.println(integerIntegerPoint5);
        integerIntegerPoint5.test(66);

        integerIntegerPoint5.print("hello");
    }
}

(五)通配符

  1. 通配符的格式:
  • 通配符:?
  • 通配符 ? 下有两个子通配符
    (1)? extends 类:设置泛型上限
    (2)? super 类:设置泛型下限

  1. 通配符存在的意义:
    解决参数统一问题,可以接收所有的泛型类型,但是又不能够让用户随意修改。
    就是在泛型类之外的方法中使用泛型类的时候,并不指定具体类型,在类使用具体参数类型的时候自动调整为类中使用的具体参数类型。
  2. 通配符的使用
    通配符在使用的时候不能修改对象的内容。
class  Message<T>{
    private T message;

    public T getMessage() {
        return message;
    }

    public void setMessage(T message) {
        this.message = message;
    }
}

public class MessageTest {
    public static void main(String[] args) {
        Message<String> mag = new Message<>();
        mag.setMessage("hello");
        fun(mag);
    }
    //使用通配符
    //此时不能修改对象内容
    public static void fun(Message<?> mag){
        System.out.println(mag.getMessage());
    }
    //此处没有使用通配符,直接使用了具体类型String,因为泛型类使用的时候使用的具体类型为String,因此此处使用String也可以,但是使用其他类型就不可以
//    public static void fun(Message<String> mag){
//        System.out.println(mag.getMessage());
//    }

}

  1. 泛型上限和泛型下限
    (1)泛型上限可以用在泛型类上,泛型方法上,不能修改内容。
    (2)泛型下限不可以用在泛型类中,只能用在方法上,可以修改内容。

(六)泛型接口

泛型接口的定义和泛型类的定义类似
在实现泛型接口时候有两种实现方式:

  1. 在子类定义时继续使用泛型;
  2. 在子类实现接口的时候给出具体类型。
    使用:
//1. 定义泛型接口
interface Person< T >{
...
}

//2. 在子类定义时继续使用泛型
class Student<T> implements Person<T>{
...
}

//3. 在子类实现接口的时候给出具体类型。
class Teacher implements Person<String>{
...
}
JavaJava中一种强大的特性,允许编写类安全且可重用的代码,能创建灵活的组件处理不同数据类,同时保持代码的简洁性和可读性,对于编写高质量Java程序至关重要[^2]。 ### 基本概念 通俗理解,让类可以像方法的参数一样传递。例如`List<String>`中的`String`就是类参数,它告知编译器该`List`只能存放`String`类的对象[^3]。 ### 使用场景 - **类安全**:在没有时,需要强制类转换,容易导致`ClassCastException`,而使用能在编译时检查类安全,避免运行时异常。 - **代码复用**:不使用时,为不同类需要编写相似的代码,使用一套代码就可以适用于多种类。 - **代码清晰度**:没有时,需要查看文档或注释才能知道集合中存储的类使用可直接从类声明了解集合中存储的类[^3]。 ### 使用方法 #### 泛型类 在实例化类的时候指明的具体类。例如: ```java class Box<T> { private T t; public void set(T t) { this.t = t; } public T get() { return t; } } // 使用 Box<String> stringBox = new Box<>(); stringBox.set("Hello"); String value = stringBox.get(); ``` #### 方法 在调用方法的时候指明的具体类。示例如下: ```java public <T> T genericMethod(Class<T> tClass) throws InstantiationException, IllegalAccessException { T instance = tClass.newInstance(); return instance; } // 使用 try { String str = genericMethod(String.class); } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } ``` ### 通配符 在代码中,问号`?`称为通配符,用来表示未知类。通配符可在多种情况下使用,如作为参数、字段或局部变量的类,有时也可作为返回类,但永远不会用作调用方法、创建泛型类或超类实例的类参数。例如: ```java public static void printList(java.util.List<?> list) { for (Object element : list) { System.out.println(element); } } ``` ### 原理 Java是通过类擦除实现的。在编译时,编译器会把泛型类信息擦除,替换为原始类(如`List<String>`会被擦除为`List`),并在必要的地方插入类转换代码,以保证类安全。 ### 最佳实践 - **合理使用泛型类方法**:根据实际需求选择合适的形式,若类参数与类的整体相关,可使用泛型类;若只与某个方法相关,则使用方法。 - **使用通配符提高灵活性**:当需要处理不同泛型类的集合时,合理使用通配符能提高代码的灵活性和复用性。 - **注意类擦除的影响**:由于类擦除,在运行时无法获取的具体类信息,编写代码时需考虑这一点。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值