对泛型的了解

目录

1、泛型

2、使用泛型的好处

3、泛型的定义

4、通配符

5、受限泛型

6、泛型接口

7、泛型方法

8、java高级--注解

8.1、预定义注解---了解

8.2、自定义注解。---初级

8.3、元注解

8.4、自定义注解---高级


1、泛型

所谓的泛型就是在类定义时,不为类中属性和方法指定数据类型,而是在类对象创建时为其指定相应的数据类型。

2、使用泛型的好处

泛型类型必须都是引用类型。不能是基本类型。

使用泛型就保证了数据类型安全问题。

public class Point<T> {
    //x坐标----
    private T x;
    //y坐标
    private T y;

    //输出坐标的值
    public void show(){
        System.out.println("x坐标:"+x+";y坐标:"+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;
    }
}
Point<Integer> p1=new Point<Integer>(10,20);//坐标为整数int--自动装箱->Integer--->Object(向上转型)
        p1.show();

        Point<Double> p2=new Point<Double>(25.5,36.6);//坐标为小数
        p2.show();

        Point<String> p3=new Point<String>("东经180度","北纬25度");//坐标为字符串
        p3.show();

3、泛型的定义

泛型可以定义在类上,接口上,方法上。 泛型类,泛型接口以及泛型方法。

泛型可以解决数据类型的安全性问题,其主要原理是在类声明时通过一个==标识表示类中某个属性的数据类型或者是某个方法的返回值及参数类型==。这样在类声明或者实例化时只要指定好需要的类型即可。

public class Test03 {
    public static void main(String[] args) {
        Info<String> info=new Info<>();
        info.setVar("hello");
        info.show();

        Info<Integer> info1=new Info<>();
        info1.setVar(15);
        info1.show();

        //如果没有指定泛型类型默认为Object,
        Info  info2=new Info();
        info2.setVar("你好");

        String o = (String) info2.getVar();//如果想使用真正的类型接受,那么必须进行强制
        System.out.println(o);

    }
}
//T标志可以任意起名.----> 那么在创建对象时,必须为每个泛型指定数据类型。
class Info<T>{
    private T var;
    public void show(){
        System.out.println("var========"+var);
    }

    public T getVar() {
        return var;
    }

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

4、通配符

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

5、受限泛型

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

[设置上限]
声明对象: 类名称<? extends 类> 对象名称;
定义类:  [访问权限] 类名称<泛型标识 extends 类>{}

[设置下限]
声明对象: 类名称<? super 类> 对象名称;
不能定义类

public class Test04 {
    public static void main(String[] args) {
         Info<Number> i=new Info<>();
         fun2(i);

         Info<Object> i3=new Info<>();
         fun2(i3);

         Info<Integer> i4=new Info<>();
         fun2(i4);
    }


    //传递的参数泛型类型必须为Number的父类或者Number类型
    public static void fun2(Info<? super Number> info){
        info.show();
    }
    //传递的参数泛型类型必须为Number的子类或者Number类型
    public static void fun(Info<? extends Number> info){
         info.show();
    }
}
//当创建该类对象时,泛型必须为Number的子类以及Number类型
class People<T extends  Number> {

}

//T标志可以任意起名.----> 那么在创建对象时,必须为每个泛型指定数据类型。
class Info<T>{
    
    private T var;
    public void show(){
        System.out.println("var========"+var);
    }

    public T getVar() {
        return var;
    }

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

6、泛型接口

public interface 接口名<泛型标志,泛型标志....>{
//下面两个是jdk1.8之后推出的方法

  //静态常量
   //抽象方法。
}

7、泛型方法

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

泛型方法的简单定义】

[访问权限] ==<泛型标识>== 泛型标识 方法名称(泛型标识 参数名称)

public class Test {
    public static void main(String[] args) {
        String hello = Student.fun("hello");
      
    }
}

class Student{

    //泛型方法: static静态成员,随着类的加载而被加载到JVM内存中。常量池
    public static <T> T fun(T t){

        return t;
    }
}

8、java高级--注解

注解的分类:

1. 预定义注解
2. 自定义注解
3. 元注解

8.1、预定义注解---了解

预定义注解就是JDK自带的一些注解,该注解被JVM而解析。

1. @Override: 重写得注解。符合重写得规则。
2. @Deprecated: 表示已过时。
3. @SuppressWarnings: 表示压制警告。
4. @FunctionInterface: 表示函数式接口。表示该接口中有且仅有一个抽象方法。

8.2、自定义注解。---初级

语法:

public @interface 注解名{
   //注解属性
}

public class Test {
    public static void main(String[] args) {
        Info i=new Info();
        i.name="讲究";
        i.show();
    }
}
//定义好注解了
@interface My{
   //注解属性
}

//使用注解
@My
class Info{
    @My
    public String name;

    @My
    public void show(){
        System.out.println("show================="+name);
    }
}

 使用注解和不使用注解没有区别?

注解本身没有任何意义,它只有被解析了,才会赋予真正的意义。

我们后会使用反射来对象注解进行解析。

像:@Override 它被JVM解析,从而使其具有相应的意义。

@Controller @RequestMapping 它被Spring框架解析,所以具有相应的意义。

8.3、元注解

  1. 定义在注解上的注解称为元注解。

1. @Target(value=可以取下面这些内容): 作用限制注解使用得位置。
    /** 表示可以作用在类,接口,枚举 */
    TYPE,

    /** 属性 */
    FIELD,

    /** 普通方法上 */
    METHOD,

    /** 方法参数 */
    PARAMETER,

    /** 构造方法上 */
    CONSTRUCTOR,

    /** 局部变量 */
    LOCAL_VARIABLE

2. @Retention:  注解什么时候生效。默认时源码 java经历了那些阶段。
      源码阶段-->字节码阶段--->运行阶段
      /**
     * 源码时生效
     */
    SOURCE,

    /**
     * 字节码时生效

     */
    CLASS,

    /**
     * 运行时生效。
     * 在JVM内存中还有该注解。
     都会被设置为运行时有效
     */
    RUNTIME
    
3. @Documented 当生产API文档时该注解还存在。

4. @Inherited 是否运行被子类继承。

//表示该注解可以使用的位置
@Target(value = {ElementType.TYPE,ElementType.METHOD})
//表示注解什么时候生效--source--class[默认字节码有效]---runtime[反射时验证]
@Retention(value = RetentionPolicy.RUNTIME)
//是否在生成api文档时存在该注解
@Documented
//子类是否能继承该注解,如果注解在定义时使用了下面这个元注解则能被子类继承。
@Inherited

8.4、自定义注解---高级

/定义好注解了
//表示该注解可以使用的位置
@Target(value = {ElementType.TYPE,ElementType.METHOD})
//表示注解什么时候生效--source--class[默认字节码有效]---runtime[反射时验证]
@Retention(value = RetentionPolicy.RUNTIME)
//是否在生成api文档时存在该注解
@Documented
//子类是否能继承该注解,如果注解在定义时使用了下面这个元注解则能被子类继承。
@Inherited
@interface My{
    String value(); //如果设置default默认值,那么在使用该注解时可以不为该属性赋值。
    String[] hobby() default {};//
}

//使用注解 如果使用注解时有且仅有一个属性没有赋值,而且该属性的名字value那么在给该属性赋值值,可以省略value
@My(value = "嘿嘿",hobby = "睡觉")
class Info{
    public String name;

    public void show(){
        System.out.println("名字:"+name);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值