gpt4 book ai didi

java - Class#getInterfaces() 和 Class#getGenericInterfaces() 返回不同长度的数组

转载 作者:搜寻专家 更新时间:2023-11-01 03:05:58 27 4
gpt4 key购买 nike

如果你上课scala.runtime.AbstractPartialFunction来自 Scala 2.10.2(我没有检查其他版本)并比较 AbstractPartialFunction.class.getInterfaces() 的输出和 AbstractPartialFunction.class.getGenericInterfaces()您可能会注意到,结果不匹配。通用接口(interface)是 scala.Function1<T1, R>scala.PartialFunction<T1, R> ,而 getInterfaces() 只返回 scala.PartialFunction .从 scala 文档中我可以看到通用信息是正确的,因为 PartialFunction 是一个 Function1。

getInterfaces 的 javadoc 说:

If this object represents a class, the return value is an array containing objects representing all interfaces implemented by the class. The order of the interface objects in the array corresponds to the order of the interface names in the implements clause of the declaration of the class represented by this object.

和 getGenericInterfaces 具有完全相同的文本。

据此(以及其他文本,包括 stackoverflow 信息)我得出结论,数组的顺序和长度是相等的。只是这里不是这样。为什么?

到目前为止,我能够用几个 java7 和 java8 重现它,没有尝试 java6 甚至 java5。

编辑:

AbstractPartialFunction 的 javap 输出(当然只有标题)是:

Compiled from "AbstractPartialFunction.scala"
public abstract class scala.runtime.AbstractPartialFunction<T1, R> implements scala.Function1<T1, R>, scala.PartialFunction<T1, R>`

在那里使用 asm 库和 Textifier 我可以看到这个头信息:

// class version 50.0 (50)
// access flags 0x421
// signature <T1:Ljava/lang/Object;R:Ljava/lang/Object;>Ljava/lang/Object;Lscala/Function1<TT1;TR;>;Lscala/PartialFunction<TT1;TR;>;
// declaration: scala/runtime/AbstractPartialFunction<T1, R> implements scala.Function1<T1, R>, scala.PartialFunction<T1, R>
public abstract class scala/runtime/AbstractPartialFunction implements scala/PartialFunction

加上一个 ScalaSigAttribute。当然这两种情况我都没有展示方法

最佳答案

// Compiled from AbstractPartialFunction.scala (version 1.6 : 50.0, super bit)
// Signature: <T1:Ljava/lang/Object;R:Ljava/lang/Object;>Ljava/lang/Object;Lscala/Function1<TT1;TR;>;Lscala/PartialFunction<TT1;TR;>;
@scala.reflect.ScalaSignature(bytes="some bytes...")
public abstract class scala.runtime.AbstractPartialFunction implements scala.PartialFunction {

类型的签名大致等同于这个 Java 声明:

class AbstractPartialFunction implements PartialFunction, Function1 {}

PartialFunction 扩展 Function1:

// Compiled from PartialFunction.scala (version 1.6 : 50.0, no super bit)
// Signature: <A:Ljava/lang/Object;B:Ljava/lang/Object;>Ljava/lang/Object;Lscala/Function1<TA;TB;>;
@scala.reflect.ScalaSignature(bytes="some bytes...")
public abstract interface scala.PartialFunction extends scala.Function1 {

这里是 the structure of a Java class file :

ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}

类型实现的接口(interface)存储在常量池中,并通过引用记录在interfaces数组中:

class signature is stored as an attribute属性数组中:

The Signature attribute records generic signature information for any class, interface, constructor or member whose generic signature in the Java programming language would include references to type variables or parameterized types.

所以这是我对正在发生的事情的有根据的猜测:

  • Class.getInterfaces() 返回 interfaces 数组的值
  • Class.getGenericInterfaces() 使用类型签名构建其返回值
  • Scala 编译器从 interfaces 数组中删除了 Function1,因为 PartialFunction 扩展了 Function1
  • Scala 编译器按原样保留类型签名

此行为不同于 Oracle JDK 从等效 Java 源生成的字节码,但它显然通过了 JVM 在加载类时所做的所有检查。

关于java - Class#getInterfaces() 和 Class#getGenericInterfaces() 返回不同长度的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22250619/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com