不兼容的类型:java.lang.Object 无法转换为 java.lang.String?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36374892/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 01:20:46  来源:igfitidea点击:

incompatible types: java.lang.Object cannot be converted to java.lang.String?

java

提问by AdventL

I am currently new to Java and have no prior programming experience, I am currently trying to code a solution to a problem proposed during my university interview :)

我目前是 Java 新手,之前没有任何编程经验,我目前正在尝试编写解决大学面试中提出的问题的解决方案 :)

//Winner rabbit variable to hold the winner of the 'race'
    String winner;
    winner = yettoracequeue.element();

Background about problem:

问题背景:

  1. assign the first item in queue to a string variable
  2. remove first item from queue
  3. assign the second item in queue to another string variable
  4. compare both variables and assign the answer to a new variable
  1. 将队列中的第一项分配给字符串变量
  2. 从队列中删除第一项
  3. 将队列中的第二个项目分配给另一个字符串变量
  4. 比较两个变量并将答案分配给新变量

I do not understand why yettoracequeue.element() is considered an object when the result is a string, e.g. Rabbit, and hence I am unable to assign it to the String variable that is winner.

我不明白为什么当结果是一个字符串时,yettoracequeue.element() 被认为是一个对象,例如 Rabbit,因此我无法将它分配给作为获胜者的 String 变量。

TIA :)

TIA :)

Edit:

编辑:

This is the full code

这是完整的代码

package queuepart;
import java.util.*;
public class QueuePart {

  static String nextline = System.getProperty("line.separator");

  public static void main(String[] args) {
    //Step 1: Create LinkedList() to assign to yettoracequeue
    Queue yettoracequeue = new LinkedList();

    //Step 2: add rabbits to queue
    int rabbitno = 1;
    yettoracequeue.add("Rabbit" + rabbitno);
    rabbitno++; 
    yettoracequeue.add("Rabbit" + rabbitno);
    rabbitno++; 
    yettoracequeue.add("Rabbit" + rabbitno);
    rabbitno++; 
    yettoracequeue.add("Rabbit" + rabbitno);
    rabbitno++; 
    yettoracequeue.add("Rabbit" + rabbitno);
    rabbitno++; 
    yettoracequeue.add("Rabbit" + rabbitno);

    System.out.println(nextline + "Items in the queue" + yettoracequeue + nextline);

    //Find first item in queue
    System.out.println(nextline + "First item in queue is " + yettoracequeue.element());

    //Assign First item in queue to racer
    String winner = yettoracequeue.element();

  }
}

回答by Stephen C

You need a typecast:

你需要一个类型转换:

    winner = (String) yettoracequeue.element();


Explanation: the way you have declared the yettoracequeuevariable, what you have is a Queueof objects; that is, a queue that couldcontain any kind of object. You have added Stringobjects to the queue, but you could have put any type of object into it.

说明:你声明yettoracequeue变量的方式,你所拥有的是一个Queue对象;也就是说,一个可以包含任何类型对象的队列。您已将String对象添加到队列中,但您可以将任何类型的对象放入其中。

So when you call yettoracequeue.element(), the compiler only knows that the object is going to be an instance of java.lang.Objector some subclass. (That is because every object is an instance of java.lang.Objector some subclass!)

因此,当您调用 时yettoracequeue.element(),编译器只知道该对象将是java.lang.Object某个子类或某个子类的实例。(那是因为每个对象都是java.lang.Object某个子类的实例!)

But when you assign the value to winner, the system needs to know that the object you assign is really a String. (If it was something else, then Stringspecific operations on it would not work.)

但是当你赋值时winner,系统需要知道你赋值的对象确实是一个String. (如果是别的东西,那么String具体的操作就行不通了。)

So what does the type-cast do?

那么类型转换有什么作用呢?

Well (String) yettoracequeue.element()does a runtime type check. It checks that the object returned by the method call is really a String:

那么(String) yettoracequeue.element()运行时类型检查。它检查方法调用返回的对象是否真的是一个字符串:

  • If the runtime type check succeeds, then it treats the type of the expression as String... and the assignment is valid.

  • If the runtime type check fails, then the runtime system throws a ClassCastException... and your program will typically fail.

  • 如果运行时类型检查成功,则它将表达式的类型视为String... 并且赋值有效。

  • 如果运行时类型检查失败,则运行时系统会抛出ClassCastException... 并且您的程序通常会失败。



Actually, there is a better way to solve the problem in this particular case. The Queuetype is actually a generic type; i.e. you can give it a type parameter. It looks like this:

实际上,在这种特殊情况下有更好的方法来解决问题。该Queue类型实际上是一个泛型类型;即你可以给它一个类型参数。它看起来像这样:

    Queue<String> yettoracequeue = new LinkedList<>();

I have now declared that yettoracequeueis a queue that contains Stringobjects. If I do that then:

我现在已经声明这yettoracequeue是一个包含String对象的队列。如果我这样做,那么:

  • When I try to add (say) an Integerobject to the queue, I will get a compilation error.

  • When I call yettoracequeue.element()the compiler will know that the queue only contains Stringobjects, and won't insist on the type cast when I assign the result to a Stringvariable.

  • 当我尝试向Integer队列添加(比如)一个对象时,我会收到编译错误。

  • 当我调用yettoracequeue.element()编译器会知道队列只包含String对象,并且当我将结果分配给String变量时不会坚持类型转换。

回答by Clashsoft

The problem in your code is that the queue is a raw type as opposed to a queue of String. To avoid the type error, you have to provide the generic type argument:

您代码中的问题是队列是原始类型,而不是String队列。为避免类型错误,您必须提供泛型类型参数:

Queue<String> yettoracequeue = new LinkedList<String>();
   // ^^^^^^

You can read more about Generic Types in the Tutorial by Oracle.

您可以在Oracle 教程中阅读有关泛型类型的更多信息。