java高级篇

本文介绍了Java中的泛型概念,包括其作用、使用场景(如避免类型转换异常),以及泛型类、通配符、受限泛型、泛型接口和方法的详细示例。同时讲解了预定义注解如@Override和自定义注解的用法,以及元注解如@Retention和@Target的应用。
摘要由CSDN通过智能技术生成

泛型:

首先要知道什么是泛型,为什么要学习泛型以及怎么使用

1.什么是泛型

泛型主要用于规范类型,数据类型被指定成了一种参数,可以用在类、方法、接口上。及参数化类型

2.为什么要学习泛型

可以指定返回的数据类型避免强制转换造成的类型转换异常

演示:没有规范类型强转String导致转换异常

/**
 * 位置实体类 
 * 属性x y 
 */
public class Point {
    private Object x;
    private Object y;

    public Point() {
    }
    public Point(Object x, Object y) {
        this.x = x;
        this.y = y;
    }
    public Object getX() {
        return x;
    }
    public void setX(Object x) {
        this.x = x;
    }
    public Object getY() {
        return y;
    }
    public void setY(Object y) {
        this.y = y;
    }
}
public class Text01 {
    public static void main(String[] args) {
        Point x = new Point("东京180",10);
        String x1 = (String) x.getX();
        String y1 = (String) x.getY();
       
    }
}

报错信息:Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap')
    at com.gjc.demo1.Text01.main(Text01.java:7)

3.泛型的使用
3.1泛型类

类引入了一个类型变量T,用尖括号(<>)括起来,并放在类名的后面。

使用泛型类解决以上问题

/**
 * 泛型类  <T>  在java中T一般表示任意类型 ,E表示集合的元素类型,K和V分别表示键和值的类型
 * 属性x y
 */
public class Point<T> {
    private T x;
    private T y;

    public Point() {
    }

    public Point(T x, T y) {
        this.x = x;
        this.y = 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;
    }
}

在创建对象时直接规范了返回类型为String,避免了强转

public class Text01 {
    public static void main(String[] args) {
        //确定泛型的具体数据类型。即在创建对象的时候确定泛型。
        Point<String> stringPoint = new Point<String>("东京180","北纬25");
        String x = stringPoint.getX();
        String y = stringPoint.getY();
    }
}
3.2通配符

<?>主要接收未知的泛型类型

/**
 * 泛型类
 * @param <T> 任意类型
 */
class Info<T>{
    private T var;
    public void show(){
        System.out.println("var========"+var);
    }
    public Info(T var) {
        this.var = var;
    }
}
public class Text02 {
    public static void main(String[] args) {
        Info<String> info1 = new Info<>("hello");
        Info<Integer> info2 = new Info<>(52);
        run(info1);
        run(info2);
    }
    public static void run(Info<?> info){  //<?> 通配符 表示可以为Info<任意类型>
        info.show();
    }
}

运行结果:

var========hello
var========52

可以看到不管是什么类型都可以接收

3.3受限泛型

在传递时限制了泛型的范围,使用extends关键字修饰为上限,限制了类型只能接收该类型及其子类型。使用super关键字修饰为下限,限制了类型只能接收该类型以及父类

上限:声明对象 类名称<? extends 范围类>对象名称

上限:声明类 【访问修饰符】 类名称<T extends 范围类>{}

只能接收该类型及其子类型

下限:声明对象 类名称<? super 范围类>对象名称

下限:声明类 【访问修饰符】 类名称<T super 范围类>{}

只能接收该类型及其父类

public class Text03 {
    public static void main(String[] args) {

        Info<Object> a = new Info<>();
        //必须为Number类或Number父类
        run01(a);   //Object为所有类的父类 可以
        Info<Number> a2 = new Info<>();
        run01(a2);  //Number本身 可以

        Info<Integer> a3 = new Info<>();
        //必须为Number类或Number子类
        run02(a3);  //Integer为Number类的子类 可以
        run02(a2);  //Number本身 可以
    }

    //设置下限最小为Number
    public static void run01(Info<? super Number> info){
        info.show();
    }
    //设置上限最大为Number
    public static void run02(Info<? extends Number> info){
        info.show();
    }
}
3.4泛型接口

泛型接口与泛型类的定义及使用基本相同

格式:修饰符 interface 接口名 <泛型标识>{

}

/**
 * 泛型接口
 * @param <T>
 */
interface Usb<T>{
    public void use(T t);
}

有两种实现方式:

第一种实现时指定泛型的类型

class Mouse implements Usb<String>{
    @Override
    public void use(String s) {
        //指定类型为String
        System.out.println("设置类型"+s);
    }
}

第二种不确定泛型的类型,直到创建对象时,确定泛型的类型

class Upan<T> implements Usb<T>{
    @Override
    public void use(T t) {
        System.out.println("没有设置类型"+t);
    }
}
        //创建对象时才指定类型
        Upan<Integer> a = new Upan<>();
        a.use(10);
        
        Upan<String> a2 = new Upan<>();
        a2.use("哈哈哈");
3.5泛型方法

泛型方法可以在是泛型类中,也可以不在泛型类,泛型方法定义格式

【访问权限】 <泛型标识> 泛型标识 方法名称(泛型标识 参数名){

}

 public <T> T aa(T t){
        System.out.println(t);
        return t;
    }

也可以多个类型

 public <T,E> T aa(T t,E e){
        System.out.println(t+"=="+e);
        return t;
    }
Text04 text04 = new Text04();
        text04.aa("aa",11); //aa==11
        text04.aa(11,11); //11==11

注解

注解的格式:@注解名,可以添加参数。注解和注释类似,都用于做出解释,注解给程序看,注释用来给人看,注解是继承了Annotation接口的接口

1.预定义注解

是java已经定义好的注解,可以直接使用,比如:

@Override:重写,使用该注解时,需要保证有继承关系,子类覆写父类的方法,方法名、参数、返回值要保持一致,修饰符不能小于父类的。从大到小依次 public->protected->默认->private 子类抛出的异常不能大于父类。否则会产生编译器错误

@Deprecated:可以修饰类、方法或字段。标识已经过时,不建议使用

@FuncationInterface: 函数式接口。要求接口有且仅有一个抽象方法

2.自定义注解

自定义注解是可以由开发者自己定义的注解

语法:

public @interface 注解名{

}

//默认可以放在任何地方使用
public @interface zj {
}
@zj
public class Text06 {
    @zj
    private String aaa;

    @zj
    private void  run(@zj String bbb){
        System.out.println(bbb);
    }
}
2.1自定义注解--属性

可以看作是注解的成员变量,使用注解时可以为这些属性赋值

格式:

public @interface 注解名{

        数据类型 属性名() default 默认值;

//如果没有设置默认值,则使用时必须给定值

}  数据类型为基本数据类型和字符串类型,以及这些类型的数组

public @interface Zidiyi{
    String value() default "";
    int age() default 0;
    String[] hobby() default {"唱","跳"};
}

这里定义了一个为Zidiyi的注解,并设置了两个属性,并设置了默认值,我们可以在下面代码中使用这个注解

@Zidiyi(value = "asd",age = 20,hobby = {"rap","篮球"})
public class Text07 {
    @Zidiyi()//默认值value="",age=0,hobby={"唱","跳"}
    public void text(){

    }
}
3.元注解

用来修饰注解的注解称为元注解

@Retention:限制注解什么时候生效。

SOURCE 源码中生效

CLASS     字节码时生效

RUNTIME 运行时生效 可以被反射读取

@Retention(RetentionPolicy.SOURCE)//源码时生效
@Retention(RetentionPolicy.CLASS)//字节码时生效  
@Retention(RetentionPolicy.RUNTIME)//运行时生效  使用最多 

@Target:限制注解可以使用在什么地方

TYPE        使用在类上

FIELD        使用在属性上

METHOD  使用在方法上

PARAMETER 使用在参数上

CONSTRUCTOR  使用在构造方法上

//可以用在类、方法和参数上
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.PARAMETER})
public @interface Zidiyi{
    
}
@Zidiyi() //类上
public class Text07 {
    @Zidiyi()// 方法上
    public void text(@Zidiyi String a){ //参数上

    }
}

@Doucumented指定注解是否包含在api文档中,默认不会包含在api文档中,如果需要被包含在javaDoc中,就需要只用@Documented注解

//包含api文档
@Documented
//可以用在类、方法和参数上
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)//运行时生效  使用最多
public @interface Zidiyi{
    String value() default "";
    int age() default 0;
    String[] hobby() default {"唱","跳"};
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值