当前位置: 首页 > 面试题库 >

如果实例未分配泛型类型,则每个循环问题中的泛型为

柴正祥
2023-03-14
问题内容

有人可以向我解释为什么明显需要为ForEachLoop实例分配通用类型吗?

为什么编译器会抱怨: 类型不匹配:无法从元素类型Object转换为String

JDK 1.5.0_09

import java.util.ArrayList;
import java.util.Collection;

public class ForEachLoop<T> {

public static void main(String[] args) {

    // Non functional version
    ForEachLoop f = new ForEachLoop();

    // Functional version
    //ForEachLoop<Integer> f = new ForEachLoop();

            // Type mismatch: cannot convert from element type Object to String
    for(String a : f.getStrings()) {
        System.out.println(a);
    }
}

public Collection<String> getStrings() {
    Collection<String> strings = new ArrayList<String>();
    strings.add("Hello");
    return strings;
}

}

问题答案:

这是一个很常见的错误:

ForEachLoop f = new ForEachLoop();

应该

ForEachLoop<Something> f = new ForEachLoop<Something>();

如果您使用原始类型(不应这样做),则编译器将擦除该实例的所有通用信息,即使它不是类型参数T,也使其与1.5版之前的代码兼容。

仅在使用Java
1.4或更低版本进行编写时才使用原始类型,在这种情况下,您不应有任何泛型。在字节码级别,该方法在类型擦除后返回Collection(原始)。通常,如果实例具有通用类型集,则当您尝试对get集合进行操作时,编译器将使用通用信息来决定应返回字符串,然后在字节码级别上,它将自动强制转换从其接收的对象集合到字符串(因为保证是字符串)。但是,如果您使用原始类型,则编译器将忽略所有常规信息,并且不再自动为您强制转换对象。

编辑 :在原始类型部分中有这些东西:

上述规则的另一个含义是,原始类型的泛型内部类本身只能用作原始类型:

class Outer<T>{
  class Inner<S> {
    S s;
  }
}

不能以部分原始类型(“稀有”类型)访问内部

Outer.Inner<Double> x = null; // illegal
Double d = x.s;

因为Outer本身是原始的,所以它的所有内部类(包括Inner)也是原始的,因此无法将任何类型参数传递给它。

仅允许使用原始类型作为对遗留代码兼容性的让步。强烈建议不要在将通用性引入Java编程语言后在代码中使用原始类型。
Java编程语言的未来版本可能会禁止使用原始类型。

尝试将参数化类型的类型成员用作原始类型是编译时错误。

这意味着对“稀有”类型的禁令扩展到对限定类型进行参数化的情况,但是我们尝试将内部类用作原始类型:

Outer<Integer>.Inner x = null; // illegal

这与我们上面讨论的情况相反。这种半烘烤类型没有实际的理由。在旧版代码中,不使用任何类型参数。在非遗留代码中,我们应正确使用泛型类型并传递所有必需的实际类型参数。

请注意,Inner类具有自己的类型参数,而与Outer类中的一个无关,并且仍然被擦除。基本上,他们不希望我们在同一实例上混合原始类型和泛型类型,因为在任何版本中都没有意义(在1.5版之前,泛型部分会出错,在1.5+版本中,不鼓励使用原始类型,并且甚至可能从将来的版本中删除)

然后还有这个:

未从其超类或超接口继承的原始类型C的构造函数(第8.8节),实例方法(第8.8节,第9.4节)或非静态字段(第8.3节)M的类型是对其类型的擦除原始类型C的静态成员的类型与对应于C的泛型声明中的类型相同。

将实际类型参数传递给未从其超类或超接口继承的原始类型的非静态类型成员是编译时错误。

这表示构造函数,实例方法和非静态字段在原始实例中将被视为原始。静态成员无论如何都将被视为通用成员,因为它们不需要访问实例。



 类似资料:
  • 问题内容: 我正在尝试采取以下措施: 和 我要坚持的是我需要在Game和Player界面中进行哪些更改才能使仿制药正常工作(我停顿了一下,但头上还有些毛:-)特别是,我迷上了Player需要在哪里进行操作知道游戏的类型,并且游戏需要知道玩家的类型。 问题答案: 这不是泛型问题(Game未键入)。 这是一个继承问题。尝试这个:

  • 问题内容: 我的问题是这样的: 为什么不能使用类Class的new T()和newInstance()实例化泛型? 问题答案: 您需要使用反射(),因为在编译时需要链接其构造函数的类是未知的。因此,编译器无法生成链接。

  • 如何获取这个类的类型?对于上下文,我使用ModelMapper,我需要类类型T从S转换为T。 背景: 我已经尝试了N种方法,其中我放置了“//一些方法来获取类型”,但没有任何效果。例如: 或

  • 理论之后,我们转移到一些实际功能上面,这会让我们更加简单地掌握它。为了不重复发明轮子,我使用三个Kotlin标准库中的三个函数。这些函数让我们仅使用泛型的实现就可以做一些很棒的事情。它可以鼓舞你创建自己的函数。 let let实在是一个简单的函数,它可以被任何对象调用。它接收一个函数(接收一个对象,返回函数结果)作为参数,作为参数的函数返回的结果作为整个函数的返回值。它在处理可null对象的时候是

  • 问题内容: 我想在Java中创建泛型类型的对象。请提出如何实现相同的建议。 注意:这似乎是一个简单的泛型问题。但是我打赌..不是。:) 假设我的类声明为: 问题答案: 你必须添加异常处理。 你必须在运行时传递实际类型,因为它不是编译后字节码的一部分,因此,没有显式提供它就无法知道它。

  • 我被分配了一个任务,创建一个列表列表,在列表中,我应该能够使用“for each”类型的“for”循环遍历列表,而不是为迭代器构建一个构造函数。问题是,当我阅读下面的代码时,我得到错误消息“只能迭代一个数组或java.lang.Iterable的一个实例”。以下是代码: 非常感谢。