Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.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

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:T-obj;obj.getClass()的类型是Class<&燃气轮机;而不是阶级<;?扩展T>;。为什么?_Java_Arrays_Generics - Fatal编程技术网

Java:T-obj;obj.getClass()的类型是Class<&燃气轮机;而不是阶级<;?扩展T>;。为什么?

Java:T-obj;obj.getClass()的类型是Class<&燃气轮机;而不是阶级<;?扩展T>;。为什么?,java,arrays,generics,Java,Arrays,Generics,在这种功能中: <T> void foo(T obj) @SuppressWarnings("unchecked") static <T> Class<? extends T> classOf(T obj) { return (Class<? extends T>) obj.getClass(); } @SuppressWarnings("unchecked") static <T> Class<? extends T

在这种功能中:

<T> void foo(T obj)
@SuppressWarnings("unchecked") static <T> Class<? extends T> classOf(T obj) {
    return (Class<? extends T>) obj.getClass();
}
@SuppressWarnings("unchecked") static <T> Class<? extends T> classOf(T[] array) {
    return (Class<? extends T>) array.getClass().getComponentType();
}

因此,
T#getClass()
的签名似乎返回一个
类,而不是
类,因为类型擦除,运行时不保留泛型数组的类型信息。实际上,JVM在内部将所有通用数组视为对象[]


如果要获取运行时类型,最好的选择可能是对数组中的第一项调用getClass()。显然,您需要找到一种方法来处理空的情况,以及包含的对象具有多种类型的情况,等等。

在Java泛型中,它只是一种用于更安全开发的源代码级工具

JVM对泛型一无所知。 Java编译器丢弃了这些信息,所有泛型类型实际上都只是运行时的对象引用。为了补偿这一点,编译器插入了必要的强制转换。 这个过程叫做(谷歌!)


要解决您的问题,您可以尝试研究数组中的单个元素(
arr[0]。getClass()
)。

基本问题是getClass()不返回类,因为它是在对象级别定义的。i、 它被定义为一个扩展对象的类。他们可以像这样定义getClass()

Class getClass(){/**/}
但事实并非如此

Class<?> getClass()
Class-getClass()

这意味着泛型不了解getClass返回的内容。

这里有几个不完全准确的答案。泛型确实是使用类型擦除实现的,但是这并不意味着所有类型信息都会丢失。编译器将把类型擦除到它能达到的最低限度

所以被擦除为字符串;这就是字符串上的getClass返回类的原因


泛型是复杂的,它们并不总是做您想要做的事情,但是有很多方法可以解决很多问题(通过改进边界、通过反射访问运行时类型信息以及传递类对象)。类型擦除实际上是一个非常聪明的解决方案,它不应该受到很多负面影响。

“要解决您的问题,您可以尝试调查数组中的单个元素。”。只要阵列中有元素!但是+1表示对话。但是数组本身不也必须知道它是什么吗?它可以抛出一个
ArrayStoreException
,因此信息必须在某个地方。如果它在编译时是一个
T[]
,编译器理论上可以安全地以某种方式获得
类。阿尔伯特:你确定它不仅仅是一个
对象[]
?小细节:类字节码中有一些编译器遗留的泛型类型信息。具体来说,字段泛型类型、方法泛型类型(参数、返回类型)和超类型泛型类型替换将被保留并可访问。但是对象实例确实没有泛型信息,只有类描述。但是
array.getClass().getComponentType()
会返回真正的类,不是吗?因此,它实际上知道运行时的数组类型。如果您创建了特定类型的数组,例如新整数[]{1,2,3,4},它将返回实际类。但如果您创建了一个泛型数组,例如,在类SomeCollection中创建了一个T[],则不会这样做——您只会得到一个java.lang.ObjectYes数组。如果您调用该示例函数(从我最初的问题中),则它必须是一个特定类型。我在这里也假设了这种情况,但我认为不可能没有这种情况。创建一个通用数组也是不可能的。啊,这很有趣!但这仍然让我想知道为什么会是这样(因为我看不出有什么具体的原因,即使使用类型擦除,对
getClass()
也有这样的限制)。我扩展了我原来的问题来说明我的意思。要回答你的编辑。。。这不会编译,因为即使A是B的子级,类也不是类的子级。您将有不兼容的返回类型。-你能让它工作的唯一方法是如果一切都回来了Class@CurtainDog:两个示例都可以编译(好吧,将第二个示例中的名称
Object
更改为其他名称)。但我的问题不是我怎么做,而是为什么会这样。已经有可能(例如,我展示的方式)使
getClass()
返回正确的类型。那么为什么不这样做呢?我认为这只是在他们修补编译器以返回类“他们本可以定义[…]”时进行的监督。事实上,你的答案接近我想知道的。问题中的原因。为什么不这样做(或者以类似的方式),这样就可以得到我想要的东西(因为Java本身实际上允许我想要的东西——参见我的示例)。原因是Java在泛型中没有返回
这种类型的机制。你必须问Java的设计者为什么会这样。我已经实现了一些接口,如果有这样的返回类型,这些接口会非常有用。相反,我不得不使用convariant返回类型的方法(数百个)
@SuppressWarnings("unchecked") static <T> Class<? extends T> classOf(T[] array) {
    return (Class<? extends T>) array.getClass().getComponentType();
}
static interface I<T> {
    Class<? extends T> myClass();
}

static class A implements I<A> {
    public Class<? extends A> myClass() {
        return this.getClass();
    }
}

static <T> void foo(I<T> obj) {
    Class<? extends T> clazz = obj.myClass(); // this works
}
static abstract class Object<T> {
    abstract Class<? extends T> myClass();
}

static class B extends Object<B> {
    public Class<? extends B> myClass() {
        return this.getClass();
    }
}

static <T> void bar(Object<T> obj) {
    Class<? extends T> clazz = obj.myClass(); // this works
}
List<String> x = new ArrayList<String>();
x.add("hello");
String hello = x.get(0);
List x = new ArrayList();
x.add("hello");
String hello = (String) x.get(0);
Class<this> getClass() { /**/ }
Class<?> getClass()