Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么Object[].class.isAssignableFrom(String[].class)==true?_Java_Arrays_Jvm - Fatal编程技术网

Java 为什么Object[].class.isAssignableFrom(String[].class)==true?

Java 为什么Object[].class.isAssignableFrom(String[].class)==true?,java,arrays,jvm,Java,Arrays,Jvm,为什么Object[].class.isAssignableFrom(String[].class)==true,而String[].getSuperClass()或getGenericInterfaces()无法获取对象[] 我检查了JDK的源代码,但我认为我自己无法得到答案。 现在,我知道JDK使用树来存储类之间的关系,并使用深度来指示其级别,Class::isAssignableFrom()搜索链,因此数组肯定在树中。而且String[]也连接到Object[] 我可以说String[]是

为什么
Object[].class.isAssignableFrom(String[].class)==true
,而
String[].getSuperClass()
getGenericInterfaces()
无法获取
对象[]

我检查了JDK的源代码,但我认为我自己无法得到答案。 现在,我知道JDK使用树来存储类之间的关系,并使用深度来指示其级别,
Class::isAssignableFrom()
搜索链,因此数组肯定在树中。而且
String[]
也连接到
Object[]

我可以说
String[]
Object[]
的一个子类吗? 或者这只是Java的另一个奇怪的东西?

在Java(和.NET)中,数组是协变的。这意味着您可以将类型为
Apple[]
的实例传递给一个方法,如果
Apple
继承了
水果,则该方法需要
水果[]
。以下行有效:

Fruit[] fruits = apples; // apples is an Apple[]
这意味着
水果[]
可从苹果[]
分配

当然,这不是很安全。假设:

void someMethod(Object[] objects) {
    objects[0] = "Hello World"; // throws at run time.
}

void test() {
    Integer[] integers = new Integer[10];
    integers[0] = 42;
    someMethod(integers); // compiles fine.
}

当您想使用数组内容(例如打印)但不想修改它时,此设计决策非常方便

因为
字符串[]
实际上可以转换/扩展为
对象[]

您可能会认为,这将测试
String[]
是否可从
Object[]
分配,测试的结果是相反的(如果
String[]
可以分配给
Object[]

此代码按预期编译和执行:

public static void main(String[] args) {
    String[] strings = new String[]{ "hello", "world" };
    printArray(strings);
}

public static void printArray(Object[] array) {
    for (Object obj : array) {
        System.out.println(obj);
    }
}
如果此对象表示一个数组类,则返回表示该对象类的类对象。

本质上是检查数组类。“子类型”和“子类”是两个不同的概念。类层次结构(即子类化)只是子类型的一部分

并有特殊情况下的子类型

数组类型的子类型规则如下(注意“>1”表示“是的直接子类型”):

  • 如果
    S
    T
    都是引用类型,则
    S[]
    >1
    T[]
    iff
    S
    >1
    T
  • Object
    >1
    Object[]
  • Cloneable
    >1
    Object[]
  • java.io.Serializable
    >1
    Object[]
  • 如果
    p
    是基本类型,则:
    • 对象
      >1
      p[]
    • Cloneable
      >1
      p[]
    • java.io.Serializable
      >1
      p[]
问题的重要部分是第一项:数组类型
X[]
是数组类型
Y[]
的子类型,当且仅当组件类型
X
是组件类型
Y
的子类型时

还请注意,严格来说,
Object[]
String[]
都不是类。它们是“唯一”类型。虽然每个类隐式地都是一个类型,但事实并非如此。非类类型的另一个示例是基本类型:
boolean
byte
char
short
int
long
float
double
都是类型,但它们不是类


造成混淆的另一个原因是,您可以很容易地获得表示这些类型的
java.lang.Class
对象。再次说明:这并不意味着这些类型是类。

您显示的代码将在运行时抛出一个
ArrayStoreException
!。。。或者根据基本类型的对象修改它,多态性的目的。哇,你从哪里得到规则的?你能给我一个链接吗?字符串[]似乎是对象[]的子类。谢谢你一个lotNo,String[]+不是Object[]的子类+!这就是我一直在说的!这是一个+子类型+,但那是不同的事情!顺便说一句,我的答案中一直有规则的链接。