Java基础知识点总结(泛型)

泛型

泛型(Generics),是指在类定义时不指定类中信息的具体数据类型,而是暂时用一个标识符来替代,当外部实例化对象的时候再来指定的具体数据类型。

//定义 A 类的时候就指定了属性是 B 类型
public class A{
    private B b;
    
    public C test(D d){
        return new C();
    }
}
public class A<T,E,M>{
    private T b;
    public E test(M m){
        return E;
    }
}
​
A<B,C,D> a = new A();

优点:这样做极大地提升程序的灵活性,提升类的扩展性,泛型可以指代类中成员变量的数据类型,方法的返回值类型以及方法的参数类型。

泛型的应用

自定义类中添加泛型

public class 类名<泛型1,泛型2,泛型3...>{
    private 泛型 属性名;
    public 泛型2 方法名(泛型3){
        方法体
    }
}
//定义 A 类的时候不指定属性的类型
package com.bsj.Demo45;
​
public class Time <T>{
    private T value;
​
    public T getValue() {
        return value;
    }
​
    public void setValue(T value) {
        this.value = value;
    }
}
package com.bsj.Demo45;
​
public class Test {
    public static void main(String[] args) {
        Time<Integer> time1 = new Time<>();
        time1.setValue(10);
        System.out.println("现在的时间是"+time1.getValue());
        Time<String> time2 = new Time<>();
        time2.setValue("十点整");
        System.out.println("现在的时间是"+time2.getValue());
    }
}

泛型用哪个字母都可以,关键是类定义处的字母和类中信息的字母保持一致。

package com.bsj.Demo46;
​
public class Time<H,M,S> {
    private H hour;
    private M minute;
    private S second;
​
    public H getHour() {
        return hour;
    }
​
    public void setHour(H hour) {
        this.hour = hour;
    }
​
    public M getMinute() {
        return minute;
    }
​
    public void setMinute(M minute) {
        this.minute = minute;
    }
​
    public S getSecond() {
        return second;
    }
​
    public void setSecond(S second) {
        this.second = second;
    }
}
package com.bsj.Demo46;
​
public class Test {
    public static void main(String[] args) {
        Time<String,Integer,Float> time = new Time<>();
        time.setHour("十点");
        time.setMinute(10);
        time.setSecond(10.0f);
        System.out.println("现在的时间是"+time.getHour()+":"+time.getMinute()+":"+time.getSecond());
    }
}

泛型通配符

有一个参数为 ArrayList 的方法,希望这个方法即可接受泛型是 String 的集合,又可以接受泛型是 Integer 的集合,怎么实现?

多态在泛型中不适用

package com.bsj.Demo47;
​
import java.util.ArrayList;
​
public class Test {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
        ArrayList<Integer> list2 = new ArrayList<>();
        test(list1);
        test(list2);
    }
​
    public static void test(ArrayList<?> list){
        System.out.println(list);
    }
}

ArrayList<?> 表示可以使用任意的泛型类型对象,这样 test 方法具备通用性了。

泛型的上限和下限

上限:表示实例化时具体的数据类型,可以是上限类型的子类或者是上限类型本身。用 extends 表示。

下限:表示实例化时具体的数据类型,可以是下限类型的父类或者是下限类型本身。用 super 表示。

类名<泛型标识 extends 上限类名>

类名<泛型标识 super 下限类名>

package com.bsj.Demo48;
​
public class Time<T> {
    public static void main(String[] args) {
        test(new Time<Integer>());
        test(new Time<Float>());
        test(new Time<Number>());
        test2(new Time<String>());
        test2(new Time<Object>());
    }
​
    /**
     * 泛型上限
     * @param time
     */
    public static void test(Time<? extends Number> time){
​
    }
​
    /**
     * 泛型下限
     * @param time
     */
    public static void test2(Time<? super String> time){
​
​
    }
}

泛型接口

接口<T>

package com.bsj.Demo49;
​
public interface MyInterface<T> {
    public T getValue();
}

实现泛型接口有两种方式:

  • 实现类在定义时继续使用泛型标识

package com.bsj.Demo49;
​
public class MyInterfaceImpl<T> implements MyInterface<T> {
​
    private T obj;
​
    public MyInterfaceImpl(T obj) {
        this.obj = obj;
    }
​
    @Override
    public T getValue() {
        return null;
    }
}
  • 实现类在定义时直接给出具体的数据类型

package com.bsj.Demo49;
​
public class MyInterfaceImpl2<String> implements MyInterface<String> {
    private String obj;
​
    public MyInterfaceImpl2(String obj) {
        this.obj = obj;
    }
​
    @Override
    public String getValue() {
        return this.obj;
    }
}
package com.bsj.Demo49;
​
public class Test {
    public static void main(String[] args) {
        MyInterfaceImpl myInterface = new MyInterfaceImpl<String>("接口");
        String val = (String) myInterface.getValue();
        MyInterfaceImpl2 myInterface1 = new MyInterfaceImpl2("接口");
        val = myInterface1.getValue();
    }
}

Java 实用类

  • 枚举

枚举 Enum,是一种有确定值区间的数据类型,本质上就是一个类,具有简洁、安全、方便等特点。

枚举的值被约束到了一个特定的范围内,只能从这个范围以内取值。

为什么要有枚举?

因为在描述某些对象的属性时,该属性的值不能随便定义,必须在某个特定的区间内取值。

出于对数据的安全性考虑,类似这种有特定取值范围的数据我们就可以使用枚举来描述。

枚举指由一组常量组成的类型,指定一个取值区间,我们只能从该区间中取值。

final class Week extends Enum{
    public static final Week MONDAY;
    public static final Week TUESDAY;
    public static final Week WEDNESDAY;
    public static final Week THURSDAY;
    public static final Week FRIDAY;
    public static final Week SATURDAY;
    public static final Week SUNDAY;
    private static final Week $VALUES[];
    
    static{
        MONDAY = new Week("MONDAY",0);
        TUESDAY = new Weeek("TUESDAY",1);
        WEDNSDAY = new Week("WEDNSDAY",2);
        THURSDAY = new Week("THURSDAY",3);
        FRIDAY = new Week("FRIDAY",4);
        SATURDAY = new Week("SATURDAY",5);
        SUNDAY = new Week("SUNDAY",6);
        $VALUES[] = (new week[]{
        MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
        })
    }
    
    public static Week[] values(){
        return $VALUES.clon();
    }
    
    public static Week valueOf(String s){
        return Enum.valueOf(s);
    }
    
    public Week(String s,int i){
        super(s,i);
    }
}

总结

Java泛型是Java 5版本引入的特性,它提供了更加安全和灵活的类型检查机制,使得程序员可以在编译时期就能够发现类型不匹配的错误。在Java泛型中,类型参数可以用在类、接口、方法等各个层次上,使得代码可以更加通用、简洁和易于维护。

以下是Java泛型的一些主要特性和用法:

  1. 泛型类:使用类型参数T来代表一个类中的某个属性或方法的类型,例如List<T>表示一个列表,其中元素的类型是T。

  2. 泛型方法:使用类型参数T来代表方法的返回值类型或参数类型,例如<T> T getFirst(List<T> list)表示获取列表中的第一个元素,并且返回值类型是T。

  3. 通配符:使用 ? 来表示某个不确定的类型,例如List<?>表示一个元素类型不确定的列表。

  4. 上界限制:使用 extends 关键字来限制类型参数的范围,例如<T extends Number>表示类型参数T必须是Number或其子类。

  5. 下界限制:使用 super 关键字来限制类型参数的范围,例如<T super Integer>表示类型参数T必须是Integer或其父类。

  6. 类型擦除:泛型只在编译期有效,在运行时会被擦除为Object,所以无法获取泛型的实际类型参数。

  7. 桥方法:为了保持泛型类型的安全,编译器会自动生成桥方法来进行类型转换,例如泛型类中的方法签名是 Object get(int index),编译器会自动生成桥方法 List<T> get(int index)。

  8. 泛型与数组:Java不允许创建泛型数组,但可以通过类型转换绕过编译器检查,所以需要注意泛型数组在运行时可能会出现ClassCastException。

总之,Java泛型虽然有一些限制和缺陷,但它仍然是一种非常有用和重要的编程特性,可以提升代码的质量和可读性,减少类型转换错误和运行错误的发生。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JavaBsj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值