英文:
Iterator expects instance of Object outside of the class which implements it
问题
Alpha.java
class Alpha<E extends Bravo> implements Iterable<Bravo> {
Bravo head;
public Alpha(Bravo head) {
this.head = head;
}
public void example() {
for(Bravo b: this) {
// This works, it's successfully recognized as an instance of Bravo.
}
}
@Override
public Iterator<Bravo> iterator() {
return new BravoIterator(this.head);
}
private class BravoIterator implements Iterator<Bravo> {
private Bravo currentBravo;
public BravoIterator(Bravo head) {
this.currentBravo = head;
}
@Override
public boolean hasNext() {
return this.currentBravo != null;
}
@Override
public Bravo next() {
Bravo data = this.currentBravo;
this.currentBravo = this.currentBravo.getNextBravo();
return data;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
}
AlphaTest.java
{...}
@BeforeEach
private void setup() {
// Assume this is a doubly linked list
Bravo bravo = new Bravo(...);
instanceOfAlpha = new Alpha(bravo);
}
public T1_checkImplementationOfIterableInterface() {
for(Bravo b: instanceOfAlpha) {
// This does not work, it expects an instance of Object.
}
}
{...}
英文:
couldn't help but feel the title is kinda vague, sorry about that. I couldn't describe it better.
I'll get a little more into detail; I'm trying to figure out how to get an iterator working the way I want it to outside of the class it's implemented in. I couldn't manage to find any information on my problem. This is part of an assignment for University, AlphaTest.java should be left as is.
I have a class, Alpha, which holds a class which follows the doubly linked list principle, Bravo. Bravo holds the link to the previous and next instance in the list.
I want to be able to iterate through the linked list with an iterator implemented in the Alpha class so that I can easily go through each instance using a for loop like this:
for(Bravo b: alphaInstance) {...}
.
I got this to work as intended within the Alpha class itself, but once I try the same outside of the Alpha class, in AlphaTest for example, it doesn't work as intended. Once I try that I'm hit with the following error:
Error:(220, 23) java: incompatible types: java.lang.Object cannot be converted to models.Bravo
It wants me to instantiate the instance as an Object like so:
for(Object o: alphaInstance) {...}
I could of course cast the object to Bravo. But that's not part of the assignment.
See code below to see what's going wrong. The problem can be found in AlphaTest.java
.
Alpha.java
class Alpha<E extends Bravo> implements Iterable<Bravo> {
Bravo head;
public Alpha(Bravo head) {
this.head = head;
}
public void example() {
for(Bravo b: this) {
// This works, it's succesfully recognized as an instance of Bravo.
}
}
@Override
public Iterator<Bravo> iterator() {
return new BravoIterator(this.head);
}
private class BravoIterator implements Iterator<Bravo> {
private Bravo currentBravo;
public BravoIterator(Bravo head) {
this.currentBravo = head;
}
@Override
public boolean hasNext() {
return this.currentBravo != null;
}
@Override
public Wagon next() {
Bravo data = this.currentBravo;
this.currentBravo = this.currentBravo.getNextBravo();
return data;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
}
AlphaTest.java
{...}
@BeforeEach
private void setup() {
// Assume this is a doubly linked list
Bravo bravo = new Bravo(...);
instanceOfAlpha = new Alpha(bravo);
}
public T1_checkImplementationOfIterableInterface() {
for(Bravo b: instanceOfAlpha) { // <---------------------------------------------[This is the problem]
// This does not work, it expects an instance of Object.
}
}
{...}
答案1
得分: 1
你误解了错误。
问题在于 instanceOfAlpha
是一个表达式,其类型最终为 Alpha
- 你省略了关于此变量的定义,但显而易见,因为你使用了原始类型创建了此变量的值。Alpha
将是一个所谓的__原始类型__ - 这是一种具有类型参数但参数缺失的类型。
问题是,原始类型有点奇怪:一旦你使用了原始类型,关于它的一切都是原始的,即使那些并未使用你未指定的泛型的部分也是如此。因此,原始 Alpha
表达式的 iterator()
方法返回一个原始 Iterator
(你可能认为它会返回一个 Iterator<Bravo>
,但实际不是这样)。因此,对其进行迭代会返回基本对象。因此,你的 for 循环是有问题的;for (Object b : instanceOfAlpha){}
可以编译通过;for (Bravo b : instanceOfAlpha){}
则不能。
修复方法通常是,当编译器在你面前抛出警告时,你不应该只是像 ¯\(ツ)/¯ 这样去理解,即我不知道那些警告是什么意思,所以我会像三只猴子一样,只希望我不理解的东西希望是完全无关紧要的。
实际情况并非如此。真正的修复方法是:修复你的泛型,以便你不会收到这些警告。
你没有粘贴足够的代码,无法准确告诉你在这里需要做什么;可能需要将 instanceOfAlpha
声明为 Alpha<?>
。更一般地说,你首次粘贴的 Alpha
类看起来你对泛型的工作原理并不是很理解;在大多数提到 Bravo
的地方,应该使用 E
来代替。泛型有点复杂;也许你想完全放弃它。完全去掉 <E extends Bravo>
部分,然后其余部分基本保持原样,也可以修复问题。
英文:
You've mischaracterized the error.
What's happening is that instanceOfAlpha
is an expression whose type ends up being Alpha
- you've elided your definition of this variable, but it seems obvious enough, as you're creating the value for this variable with a raw type as well. Alpha
would be a so-called raw type - a type that has type parameters, but where the parameters are missing.
The thing is, raw types are a tad odd: Once you go raw, everything about it is raw, even things that aren't using any of the generics you failed to specify. Thus, the iterator()
method of your raw Alpha
expression returns a raw Iterator
(you'd think it returns an Iterator<Bravo>
, but it does not). And therefore, iterating over it returns basic Objects. And therefore, your for loop is broken; for (Object b : instanceOfAlpha){}
would compile; for (Bravo b : instanceOfAlpha){}
won't.
The fix is generally that when the compiler throws warnings in your face that you shouldn't just go ¯_(ツ)_/¯ I don't know what those mean so I'll just be like the 3 monkeys and just wish that whatever I don't understand is hopefully utterly irrelevant.
It's not. The real fix is: Fix your generics so you don't get these warnings.
You haven't pasted enough code to tell you exactly what you need to do here; probably make instanceOfAlpha
be declared as a Alpha<?>
. More generally, your first paste (of your Alpha class) looks like you just don't get how generics works; most of the places that mention Bravo
in that should have been using E
instead. generics is a little tricky; perhaps you want to just opt out altogether. Get rid of the <E extends Bravo>
part entirely, and then leave the rest pretty much as is, that would also fix things.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论