将类型“放置”在类中是什么意思?

时间:2019-09-07 19:27:02

标签: java generics

我正在阅读有关通用类型的Oracle教程,第一段确实让我很头疼。该页面位于https://docs.oracle.com/javase/tutorial/java/generics/types.html,该教程以名为“ Box”的类开始:

public class Box {
private Object object;

public void set(Object object) { this.object = object; }
public Object get() { return object; }
}

下面的段落也是我一生都无法理解的一段,它的内容是:

  

由于它的方法接受或返回一个Object,因此只要它不是原始类型之一,就可以随意传递任何所需的对象。在编译时无法验证类的使用方式。代码的一部分可能会将Integer放在框中,并期望从中取出Integer,而代码的另一部分可能会错误地传入String,从而导致运行时错误。

最后一句话对我来说绝对没有意义,而且我已经阅读了该特定页面的其余部分,但仍然无法确切知道他们想说的是什么,感觉好像我错过了大部分内容课。将某些东西“放置”在盒子里是什么意思?

我已经尝试了一切,我尝试以一千种不同的方式实例化Box类,这才有意义,它们都导致编译时错误而不是运行时错误。无论我从哪个角度看,我都无法理解这一点,难以理解这意味着什么

4 个答案:

答案 0 :(得分:5)

由于我们处于Box类的上下文中-一个类是物理盒子的抽象-将整数“放置”到盒子中只是说“设置{{1 }}字段插入object”的实例。

至于您的评论:

  

好像他们首先说我可以通过任何东西,然后他们说我不能通过

这就是最后一句话的意思:您可能会有这样的代码:

Integer

本教程所指的“代码的另一部分”是“ ...”部分。如果“ ...”实际上有这样的一行:

Box b = new Box();
b.set(1); // I've put an integer into the box, I should be able to get integers out of it later on

...

Integer i = (Integer)b.get();

然后最后一行将引发异常。

泛型通过使类似b.set("String"); // I forgot that I'm supposed to only put Integers in the box 的编译器错误来解决此问题。

答案 1 :(得分:0)

Box的每个实例都有一个字段Object object。将Box中的内容“放置”表示“将该字段设置为值”(通过使用某个参数调用set(...)方法)。

例如,让我们假设我们有一个Box box = new Box();。如果我们调用box.set("Hello"),则box的{​​{1}}将被设置为object。结果,我们可以String "Hello",并且String s = (String) box.get();将引用s。由于String "Hello"返回get(),我们必须强制转换结果。

现在想象有人打电话给Objectbox.set(new Integer(10));不是Integer,并且String也不是String的超类。因此,当我们现在调用Integer时,对String s = (String) box.get()的强制转换将在运行时失败,并带有String

如果我们有可能以某种方式声明我们要使用的框将容纳ClassCastExceptionInteger,则可以在编译时检测到该错误,或者无论我们要存储在其中。那就是泛型出现的地方。我们可以这样写

String

有了这个功能,我们可以创建包含public class Box<T> { private T t; public void set(T t) { this.t = t; } public T get() { return t; } } Box)的String和包含Box<String> stringBox = new Box<String>();({{1} }。以下是一些情况及其各自行为的列表:

Box

我们将问题检测从运行时移到了编译时,并完善了fail-fast设计。很好,不是吗?

答案 2 :(得分:0)

以下是该段落所讨论的情况:

该代码可以编译并成功运行。

Box b = new Box();
b.set(42.0);
double root = Math.sqrt((Double)b.get());
System.out.println(root);

该代码可以编译,但是有运行时错误。

Box b = new Box();
b.set("hello");
double root = Math.sqrt((Double)b.get());
System.out.println(root);

标题为“ Place”的问题的真实答案仅用于本教程试图使用的方框隐喻。他们只是在谈论调用set方法。

答案 3 :(得分:-1)

老实说,我认为这只是指课程,而不是虚构的“盒子”。泛型允许您限制在该类的特定实例中可以使用哪些数据。使用Objects代替Generics不会有相同的限制-由于Java中的所有类都是Object的子类,因此您可以将任何数据类型传递给它,这可能会导致Java将尝试对这些对象执行某些操作/调用方法时发生运行时错误。