美文网首页
Java数组和类型

Java数组和类型

作者: 风干鸡 | 来源:发表于2016-12-22 15:35 被阅读0次

ArrayStoreException

之前一直以为数组的元素类型必须完全相同,不然运行时会报ArrayStoreException,比如这样:

public class Test {
    public static void main(String[] args){
        Object[] objects = new String[10];
        objects[0] = new Test();
    }
}

但是看到规范上面的这一句:

If the type of the value being assigned is not assignment-compatible (§5.2) with the component type, an ArrayStoreException is thrown.

Chapter 10. Arrays

他既然这么说,数组的元素应该是可以不同类型。所以尝试了一下,有以下两种种情况:

  1. Array Creation Expressions
public class Test {
    interface Noface {}

    static class A implements Noface {}

    static class B implements Noface {}

    public static void main(String[] args){
        Noface[] nofaces = new Noface[2];
        nofaces[0] = new A();
        nofaces[1] = new B();
    }
}

不会有问题。相同的,创建一个父类的数组,用子类对象赋值给数组元素也不会有问题。
当然这很显然了

  1. Array Initializers
public class Test {
    interface Noface {}

    static class A implements Noface {}

    static class B implements Noface {}

    public static void main(String[] args){
        Noface[] nofaces = {new A(), new B()};
        System.out.println(nofaces.getClass());
    }
}

输出:class [Ljava.lang.Object
这样也是没问题的,而且可以看到数组的类型是左侧的引用类型。反编译一下:

$ javap -c com.util.Test

    Code:
       0: iconst_2
       1: anewarray     #2                  // class com/util/Test$Noface

创建一个大小为2的Noface数组,这两段代码其实是等价的。
非基础类型数组实质上是一组引用,引用的类型完全相同,数组元素赋值也就是给对应位置的引用赋值,只要赋值的对象与数组元素类型相同或者是他的子类,就是assignment-compatible

类型

Java的数组是协变的,也就是说当类A是类B的父类的时候,A[]=new B[size]是允许的,这与功能类似的集合类不一样,ArrayList<A> list = new ArrayList<B>()就会报错。因为A[]是B[]的超类型,而ArrayList<A>不是ArrayList<B>的超类型。

If S and T are both reference types, then S[] >1 T[] iff S >1 T.

注:iff是if and only if的意思,并不是笔误。

而泛型的父子关系就比较复杂了

Given a generic type declaration C<F1,...,Fn> (n > 0), the direct supertypes of the parameterized type C<T1,...,Tn>, where Ti (1 ≤ i ≤ n) is a type, are all of the following:

D<U1 θ,...,Uk θ>, where D<U1,...,Uk> is a generic type which is a direct supertype of the generic type C<T1,...,Tn> and θ is the substitution [F1:=T1,...,Fn:=Tn].

C<S1,...,Sn>, where Si contains Ti (1 ≤ i ≤ n) (§4.5.1).

The type Object, if C<F1,...,Fn> is a generic interface type with no direct superinterfaces.

The raw type C.

4.10. Subtyping

简单举例解释一下:

  • List<A>ArrayList<A>的超类型,因为ListArrayList的父类,而且参数化类型完全相同
  • ListList<A>的超类型,因为Listraw type
  • List<? extends A>List<A>的超类型,因为? extends A contains A

contain

A type argument T1 is said to contain another type argument T2, written T2 <= T1

? extends T <= ? extends S if T <: S

? extends T <= ?

? super T <= ? super S if S <: T

? super T <= ?

? super T <= ? extends Object

T <= T

T <= ? extends T

T <= ? super T

在库函数中经常会见到这样的东西 <T extends Comparable<? super T>>, 也是出于这样的原因。

heap pollution

  • 我发现有些东西起个名字就会显得很高大上*

相关文章

  • Java集合之List、Map、Set

    Java数组和集合 Java数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),而Jav...

  • Java数组和类型

    ArrayStoreException 之前一直以为数组的元素类型必须完全相同,不然运行时会报ArrayStore...

  • Java数组

    Java数组 1.声明数组 在java中声明数组有两种形式:数组元素类型名[] 数组名;数组元素类型名 数组名 [...

  • java 数组

    java数组:相同类型数据的有序集合 (数组元素的数据类型必须相同) 1. java 创建数组变量 数组中已有元素...

  • 2. Java数组类型及其操作

    1. 数组 定义一个数组类型的变量,使用数组类型“类型[]”,例如,int[],String[]。Java的数组有...

  • Java 基础2

    1.Java数组 数组的创建 int(数据类型)[] arr(数组类型变量) = new int[10(数组的长度...

  • Java入门:数组

    Java数组 数组概念:是相同数据类型的有序集合,每个元素具有相同的数据类型。数组类型:数组属于引用类型,从Obj...

  • Java学习之数组

    标签: java 数组 声明数组语法: 声明并开辟数组: 数组的数据类型 数组是引用类型。 动态初始化数组 先开辟...

  • 算法(第四版)读书笔记 第一章

    y7## Java基础 数组 创建数组 声明数组的类型和名字 创建数组 初始化数组 二维数组 静态方法 调用 方法...

  • Java 数组

    Java 中,数组是一种引用类型。 Java 中,数组是用来存储固定大小的同类型元素。 数组对象(这里可以看成一个...

网友评论

      本文标题:Java数组和类型

      本文链接:https://www.haomeiwen.com/subject/wcqhvttx.html