泛型的笔记

一、什么是泛型?

泛型:类在定义时不为类中的属性,方法(返回值,参数)设置数据类型,在创建该类的对象时为其指定相应的数据类型。

二、为什么需要使用泛型?

例子:定义个point类,属性:x坐标和y坐标

要求:x坐标和y坐标的值

(1)x坐标和y 坐标的值都是整形。

(2)x坐标和y 坐标的值都是小数。

(3)x坐标和y 坐标的值都是字符串。

思考:x和y属性的类型。Object,因为Object是所有类的父类,由于多态

public class Test01 {
    public static void main(String[] args) {
        Point p1=new Point(15,25);//值都是整数
        Point p2=new Point(15.5,25.5);//值都是小数
        Point p3=new Point("东经150度","北纬30度");//值都是字符串

        System.out.println(p1);
        System.out.println(p2);
        System.out.println(p3);
    }
}
//思考: 我可以创建一个Point对象,而该对象在赋值时x坐标为整数,y坐标为字符串。这个程序会不会报错。【不会】
// 破坏了数据类型一致的安全问题。
class Point{
     private Object x;
     private Object y;

    public Point() {
    }

    public Point(Object x, Object y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return "Point{" +
                "x=" + x +
                ", 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 类名<T,E...>{        //T,E都是泛型标志

        public  T  属性名;

        public  T  getXXX(){}

        public void  setXXX(T  t){}

}

        

public class Test02{
    public static void main(String[] args) {
         Point<Integer> p1=new Point<>(15,25);
         Point<Double> p2=new Point<>(15.5,25.5);
         Point<String> p3=new Point<>("东经150度","北纬300度");

         Point p4=new Point();//如果没有为泛型设置类型,则默认为Object

        System.out.println(p1);
        System.out.println(p2);
        System.out.println(p3);
    }
}
//T:习惯用T表示泛型表示。Type
class Point<T>{
     private T x;
     private T y;

    public Point() {
    }

    public Point(T x, T y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return "Point{" +
                "x=" + x +
                ", 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;
    }
}

四、通配符

在开发中对象的引用传递是最常见的,但是如果在泛型类的操作中,在进行引用传递时泛型类型必须匹配才可以传递,否则是无法传递。

public class Test03 {
    public static void main(String[] args) {
            Info<Integer> i=new Info<>();
            i.setVar(15);
            fun(i);

            Info<Double> j=new Info<>();
            j.setVar(15.5);
            fun(j); //泛型的引用类型传递要求类型匹配而且泛型也要匹配。
           //思考: 泛型能否让他传递任意类型? 可以不写 或者使用通配符。
    }
    public static void fun(Info<?> a){
         a.show();
    }
}

class Info<T> {
    private T var;//成员变量

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

    public void show() {
        System.out.println("var=======" + var);
    }
}

五、受限泛型

在引用传递中,在泛型操作中也可以设置一个泛型对象的范围上限和范围下限。范围上限使用extends关键字声明,表示参数化的类型可能时所指定的类型或者是此类型的子类,而范围下限使用super进行声明,表示参数化的类型可能是所指定的类型或者此类型的父类型。

格式:

设置上限:

声明对象:类名称<? extends 类> 对象名称;

定义类:【访问权限】类名称<泛型标识  extends  类>{}

设置下限:

声明对象:类名称<?  super   类>  对象名称;

定义类:【访问权限】类名称<泛型标识   super  类>{}

public class Test04 {
    public static void main(String[] args) {
        Info<Integer> a=new Info<>(25);//创建一个泛型为Integer的info对象
        fun1(a);
        Info<Number> b=new Info<>(25);
        fun1(b);
        Info<Double> f=new Info<>(25.5);
        fun1(f);
       //=======================================================
        Info<String> c=new Info<>("hello");
        fun2(c);
        Info<Object> o=new Info<>(true);
        fun2(o);
    }
    //设置参数的泛型上限。
    public static void fun1(Info<? extends Number> a){
         a.show();
    }
    //设置了泛型的下限。必须为String或String的父类
    public static void fun2(Info<? super String> b){
        b.show();
    }
}

class Info<T> {
    private T var;

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

    public void show() {
        System.out.println("var======" + var);
    }
}

六、泛型接口

在JDK1.5之后,不仅可以声明泛型类,也可以声明泛型接口,声明泛型接口和声明泛型类的语法类似,也是在接口名称后面加上<T>,格式如下:

【访问权限】  interface   接口名称<泛型标识>{

}

6.1泛型接口的两种实现方式

泛型接口定义完成之后,就要定义此接口的子类,定义泛型接口的子类有两种方式

①直接在子类后声明泛型

②直接在子类实现的接口中明确的给出泛型类型

public class Test05 {
    public static void main(String[] args) {
         USB<Integer> a=new Upan<>();

         USB<String> b=new Mouse();
    }
}
//泛型接口。
interface USB<T>{

    public T show();

}
//在类创建时也使用该泛型
class Upan<T> implements USB<T>{
    @Override
    public T show() {
        return null;
    }
}
//在创建类时为泛型接口指定具体的数据类型。
class Mouse implements USB<String>{
    @Override
    public String show() {
        return null;
    }
}

6.2泛型方法

泛型方法的定义与其所在的类是否是泛型类是没有任何关系的,所在的类可以是泛型类,也可以不是泛型类

泛型方法的格式:

public  <泛型标识>  泛型标识  方法名(){}
public class Test {
    public static void main(String[] args) {
        String hello = fun("hello");
    }
    public static <T> T   fun(T t){
        return t;
    }
}

七、注解

注释:注释给程序员看的,方便理解该行的代码意思

注解:注解是给程序看的

7.1注解的分类

1.预定义注解

2.自定义注解

3.元注解

7.2预定义注解

JDK中自带的一些注解,JVM可以解析这些注解

1.@Override:表示方法重写的注解,如果使用该注解那么必须符合重写的规则

2.@Deprecated:表示过时的注解,使用该注解表示该方法已经过时了

3.@SupressWarnings:表示忽略警告的注解。使用该注解可以去除警告

4.@FUnctionInterface:表示函数式接口

package com.ykq.demo07;
@SuppressWarnings(value = "all")//忽略所有的警告
public class Test {
    public static void main(String[] args) {
         int a=15;
    }
}
@FunctionalInterface //函数式接口 表示该接口中有且仅有一个抽象方法。
interface  USB{
    public void fun();
    default  void show(){
        
    }
}
public class Test07 {
    public static void main(String[] args) {
        Date date = new Date();
        String s = date.toLocaleString();//把时间进行格式
        System.out.println(s);
        Info i=new Info();
        i.show();
    }
}

class Info {
    private String name;


    @Deprecated //表示该方法为过时方法,如果调用该方法会出现删除线
    public void show(){
        System.out.println("~~~~~~~~~~~~~~~~");
    }



    @Override //表示方法重写的注解。使用该注解必须保证符合重写的规则
    public String toString() {
        return "Info{" +
                "name='" + name + '\'' +
                '}';
    }
}

7.3自定义注解

如果没有人解析该注解,那么该注解没有任何意义。(反射来解析该注解使其有意义)

@Controller:那是因为Spring框架解析了该注解

@Override:因为JVM解析了该注解

格式:

public @interface  注解名{

        注解的属性

}

public class Test08 {
}
//自定义注解
@interface MyAnnotation{

}
//使用自定义的注解
@MyAnnotation
class Info{
     @MyAnnotation
     private String name;

     @MyAnnotation
     public void show(){

     }
}

7.4元注解

定义在注解上的注解称为元注解

@Target: 该注解使用的位置。
    //作用在类上
    TYPE,

    //作用在属性上
    FIELD,

    //作用在方法上
    METHOD,

    //作用在方法参数上。
    PARAMETER,

    //作用在构造方法上
    CONSTRUCTOR,

    //作用在局部变量上
    LOCAL_VARIABLE,

    //作用在注解上
    ANNOTATION_TYPE,

    //作用在包上
    PACKAGE,

    //类参数
    TYPE_PARAMETER,
    TYPE_USE
@Retention: 作用什么时候生效。 默认为SOURCE
    SOURCE:源码上生效
    ClASS:字节码上生效
    RUNTIME:运行时生效----几乎都使用该值。
@Documented: 表示该注解生成API文档时是否存在。
@Inherited:  该注解是否允许被子类继承。

八、自定义注解的属性:

格式:

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

注意:数据类型可以是  基本数据类型  字符串  数组   枚举  注解

@Target(value=ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface  A{
    //定义注解的属性value. 格式: 数据类型 属性名();
    //数据类型: 基本数据类型 字符串 枚举 数组[基本 字符串] 注解类型
    String value() default "/hello";
    String name() default "wyt";  //设置默认值。
    String[] hobby() default {}; //如果只有一个值 那么可以省略{}
//    MyEnum a();
}

@A()  //比如@RequestMapping(value="/hello")
                      // 如果只为value指定值那么可以省略value名称
class Student{

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值