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

原文地址:https://www.cnblogs.com/lin7155/p/14860917.html