zoukankan      html  css  js  c++  java
  • Java学习树--6 类,泛型

    类声明

    类修饰符 public protected private abstract static final strictfp,其中strictfp是关于浮点数计算的,很少用到。


    抽象类,被认为是不完整的类,不能被实例化。
    普通类也可以有抽象方法,及不完整的方法,其子类如果想要实例化,那么必需重写抽象方法。

    abstract class Point {
    int x = 1, y = 1;
    void move(int dx, int dy) {
    x += dx;
    y += dy;
    alert();
    }
    abstract void alert(); //抽象方法的声明
    }
    

    注意:接口中的方法也是抽象的。


    final class 是一个不变的类,不能被继承。
    static class 是一个静态类,不能被实例化,静态类中所以的方法都是static方法,不能有常规的方法,因为static不能被实例化。


    generic class and type parameters泛型类和类型变量,一个类是泛型的,那么它声明一个或多个类型变量


    泛型类定义了一组参数类,但是在运行期间,这些定义实例化的泛型类公用同一个类。Java虚拟机中的catch机制仅对非泛型类有效

    Vector<String> x = new Vector<String>();
    Vector<Integer> y = new Vector<Integer>();
    boolean b = x.getClass() == y.getClass();   //true
    

    Inner class 内部类是一个嵌套类,是以下的几个类型之一 1. 成员类不是显示或者隐式的static类 2.非隐式静态的local class,局部类 3.匿名类
    以下类是隐式静态的,不是内部类。 内部类是嵌套类的子集,常见的说法静态内部类不是内部类,是一个嵌套类。 1. 成员枚举类 2. 局部枚举类 3. 成员记录类,局部记录类 4. 接口成员类
    所以适用于嵌套类的规则都适用于内部类
    class HasStatic {
    static int j = 100;
    }
    class Outer {
    class Inner extends HasStatic { //Inner是内部类,VeryNestedButNotInner,NestedButNotInner 都不是内部类
    static {
    System.out.println("Hello from Outer.Inner");
    }
    static int x = 3;
    static final int y = 4;
    static void hello() {
    System.out.println("Hello from Outer.Inner.hello");
    }
    static class VeryNestedButNotInner
    extends NestedButNotInner {}
    }
    static class NestedButNotInner {
    int z = Inner.x;
    }
    interface NeverInner {} // Implicitly static, so never inner
    }
    

    enclosing instance 封闭实例,静态类中的成员类不能访问外部类的变量,而方法中的局部类可以访问外部的类变量。

    class Outer {
    int i = 100;
    static void classMethod() {
    final int l = 200;
    class LocalInStaticContext {
    int k = i; // Compile-time error
    int m = l; // OK
    }
    }
    void foo() {
    class Local { // A local class
    int j = i; //OK
    }
    }
    }
    

    superclasses subclasses
    Object是原始类,没有超类,final类没有子类,enum class也没有继承子句,record class也是同样道理,不然会编译出错。
    某些情况下,是不会直接使用extend显示超类
    比如大部分没有extends子句的类默认超类是Object;一个enum class E,直接超类是Enum


    直接超类 direct superclass非常重要,它用于各种派生。 直接超类是用extend声明的超类,比如 A extends B


    超类关系是直接超类的传递闭包关系,及超类的关系是可以传递的。
    比如类B是类C的直接超类,类A是类B的超类,那么类A是类C的超类。


    类方法
    方法签名:方法名+方法的参数类型
    方法修饰符public protected private abstract static final synchronized native strictfp
    方法使用throws声明异常
    方法的继承,重写,隐藏
    重载,方法名相同,但是参数不同


    构造函数,如果子类有直接超类,那么每次写构造函数前,都需要先调用父类的构造函数,super();


    Enum类是隐式final,不是static类,但是嵌套enum类却是静态类。
    enum类的性能比静态类好。


    Java中的record关键词,是14版本添加的,是数据模型相关,节省实体类的编写。

    常见的通配符
    ? 表示不确定的Java类型,T 具体的一个Java类型,K,V Java中的键值对,E 代表Element

    class类详解

    Class 是一个泛型类,本质上是Class Class<?>代表未知类型的类类型
    class实例代表了在Java运行期间的所有类和接口,class类没有公共的构造函数,在Java虚拟机中从类文件派生类对象,自动创建Class实例,通过以下的方法
    ClassLoader::defineClass
    java.lang.invoke.MethodHandles.Lookup::defineClass
    java.lang.invoke.MethodHandles.Lookup::defineHiddenClass


    class的唯一静态方法
    Class.forName() 返回一个class对象

    class类的实例方法

    1. class.isXXX() class.isArray() class.isAnnotation()
    2. class.toGenericString() 返回class对象的定义,如 public class java.util.LinkedList
    3. class.cast(Object o) 类型转换,o转换成为class文件的类型; class.asSubclass()成为子类型
    4. class.getXXX()


      class.getClassLoader() 获取类加载器,Java本身设定的类返回null,程序员创建的会返回AppClassLoader。
      class.getAnnotations() 返回次元素上的注解 getDeclaredAnnotations() 返回直接存在次元素上的注解
      class.getConstructors()返回公共的构造函数 getDeclaredConstructors()返回所以的构造函数 次中方法,还要Field,Method类似
      class.getComponentType() 返回数组类型的元素类型,比如int[] 返回int,Object[]返回Object


      getDeclaredClasses() 返回class内部定义的所以嵌套类,嵌套接口等


      Type[] getGenericInterfaces() 返回class类实现的所以接口Type
      Type getGenericSuperclass() 返回class类直接继承的超类
      getInterfaces() 返回class类实现的所以接口的class类

    泛型体系中的上界和下界
    上界<? extends >
    下界<?super >
    比如有People超类,有子类Man,Woman,Man又有子类Boy.

    List<? extends People> list;
    list=new ArrayList<People>();
            list=new ArrayList<Man>();
            list=new ArrayList<Woman>();
            list=new ArrayList<Boy>();
    list.add(new People) ;//编译错误,list不知道集合list的具体子元素类型
    
    for(People p:list){  } //编译通过
    

    list这个引用只能指向的集合,是People和七其派生类的集合。不能指向与People没有关联的集合。 同时集合里面的元素类型是People或者其子类类型。 上述意味着在编辑阶段无法确定集合元素中的具体的类型,所以不能往list集合元素中添加任何类型的元素,只能从集合list中获取元素。 因为集合中的元素都有一个共同的父类,所以可以利用People直接接受元素,这是因为子类向父类转换,是隐式转换。
    下界
    List<? super Man> list;
    list=new ArrayList<Man>();
            list=new ArrayList<People>();
            //list=new ArrayList<Boy>();
            //list=new ArrayList<Woman>();
    list=new ArrayList<>();
    //        list.add(people);
            list.add(man);
            list.add(boy);
    
            for (Object man1:list){
                System.out.println(man1);
            }
    

    泛型下界,super指明集合list元素中的集合,一定是Man或者Man的子类,所以list引用只能指向ArrayList(),ArrayList() Man和其父类的集合,因为只有这种集合才能保存集合元素能同时存储Man和Man的子类,如果list引用指向new ArrayList()Boy集合的引用,那么集合里面只能存储Boy元素,不能存储Man类型和其他的子类类型。
    list集合可以使用add方法添加,但是如果需要便利集合,那么只能使用Object,因为Object是他们共同的父类,而且子类向父类转换不需要强制转换。


    额外补充List<?> list引用可以接受任何类型的集合引用,但是不能存储元素,只能往外读取元素。
    List<? extends T>list 指向的集合中存储的元素是单一类型,但这些元素类型必需是T或者T的派生类
    List<? super T>list指向的集合元素不是单一类型,只有父类是T就能存储。


    上界extends 表面list指向的集合是People和其派生类,最高是People。【People,Man,Woman,
    下界super 表面list指向的集合 People和父类,最低是People。 Object,People】


    依据PECS原则,频繁地取使用上界通配符,频繁地存储使用下界通配符。


    TypeVariable>[] class.getTypeParameters()
    ### 接口Type,其下的4个子接口

    ParameterizedType 泛型类型,表示那些泛型类型,比如Map<String,Integer>,List<?>,People<K> 这些带有<>都是泛型类型,其下的方法可以获得<>里面的Type。


    TypeVariable 泛型参数类型,不是具体的某一个类型,而是泛型参数,比如T,K,V,<K extends People>,<T super Man>,可以获得上界和下界


    WildcardType 通配符类型,?,可以理解成为单独?,<? extends People>,<? super Man>


    GenericArrayType 泛型数组类型,T1[] array,其中T1[]就是泛型数组类型


    总结ParameterizedType是具体的泛型类型,而TypeVariable,WildcardType就是具体里面的<>相关内容。


    如何获得相关Type,从class,field实例的方法中获取
    比如field#getGenericType() 方法,获取ParameterizedType类型,只有这个方法能获取这个类型
    比如class#getTypeParameters()方法,返回的是TypeVariable数组




    通配符是 ?WildcardType 类型,? super 也是WildcardType,这里的? super Man中的Man是下界,不是Type类型
    具体的比如T,K是TypeVariable类型
    某个类比如public class myClass<T,K> 类声明中的,T,K是TypeVariable类型
    但是private myClass<String,Integer> c;中的myClass<String,Integer>是ParameterizedType类型,但里面String,Integer不是具体的Type类型


    GenericArrayType
    getGenericComponentType()


    ParameterizedType
    getActualTypeArguments() //会将<>里面的内容封装成为Type接口,返回返回一个Type数组。Type数组可以转换成为TypeVariable或者具体的类型,就是T,String这种集合。
    getRawType() //比如List<?> 会返回<>左边的内容,及List
    getOwnerType()//返回申明这个类的类型,内部类返回父类

    TypeVariable,


    WildcardType
    getLowerBounds()
    getUpperBounds()


    但是在不同版本的Java中,Type不同接口的方法不同。

    泛型体系总结

    创建泛型类,有两种形式

    public class Generi<T>{
    }
    public class Gene<T extends Number>{
    }
    

    Class Constructor Method Field Type
    class实现了Type接口

    https://blog.csdn.net/xxxzhi/article/details/49616577
    https://blog.csdn.net/zymx14/article/details/78073757
    https://blog.csdn.net/jdsjlzx/article/details/70479227?utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-4.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-4.control

  • 相关阅读:
    斯特林反演
    子集计数
    快速求斯特林数总结(洛谷模板题解)
    min-25筛总结
    数学笔记
    [WC2018]即时战略(LCT,splay上二分)
    [WC2018]通道(乱搞,迭代)
    Python requests 多线程抓取 出现HTTPConnectionPool Max retires exceeded异常
    Python监控服务器利器--psutil
    gevent
  • 原文地址:https://www.cnblogs.com/lin7155/p/14860917.html
Copyright © 2011-2022 走看看