¿Qué causa el error "Tipos de operandos incompatibles"?

Estoy tratando de implementar la interfaz iSortableStack a través de una clase.

Esta es mi función principal,

public class SampleStack<E> {
    E ch;

    @SuppressWarnings("unchecked")
    public static void main(String[] args) throws IOException {
        ISortableStack<Character> s = new SortableStack<Character>();
        SampleStack demo = new SampleStack();
        while ((demo.ch == System.in.read()) != '\n')
            if (!s.isFull())
                s.push((Character) demo.ch);
        while (!s.isEmpty())
            System.out.print(s.pop());
        System.out.println();
    }
}

Pero recibo un error, en esta línea,

while ((demo.ch == System.in.read()) != '\n')

Error: tipos de operandos incompatibles Object e int

Que esta mal aquí ?

preguntado el 27 de agosto de 11 a las 16:08

y si declaras demo como SampleStack<Character>? -

En lugar de suprimir las advertencias (como ha hecho con el @SuppressWarnings("unchecked")), debe prestar atención a los consejos del compilador. Si no entiende ese consejo, entonces debería leerlo hasta que lo entienda (que es lo que está haciendo preguntando aquí, una excelente opción). En general: no ignore las advertencias a menos que sepa lo que significan. -

¿Qué es exactamente una pila ordenable, aparte de una contradicción en los términos? -

5 Respuestas

Aquí hay dos problemas graves que no tienen nada que ver con los genéricos.

En primer lugar, demo.ch == System.in.read() es un boolean expresión. El resultado de read() (un int) se incluirá automáticamente en un Integer, y la identidad de ese objeto se probará contra demo.ch (cual es null).

Creo que lo que quieres aquí es el operador de asignación, =. Esto asignará el read() resultado de demo.ch.

El siguiente problema es que parece que esperabas demo.ch a ser un Character (según los modelos que esté utilizando). Sin embargo, está intentando asignar un int (el resultado de read()) a ella. Los tipos primitivos se pueden "encuadrar automáticamente" cuando sea necesario, es decir, se pueden convertir en un objeto contenedor como Character or Integer, pero solo cuando el valor a convertir es una expresión constante que puede ser representada por el tipo de destino. Aquí, el valor es variable, por lo que la conversión no se puede realizar implícitamente.

Puede solucionar esto lanzando explícitamente el read() resultado a un char, y luego dejar que el auto-boxing lo convierta en un Character, pero eso ocultaría EOF, que está representado por un valor de -1. Recomiendo usar algo como esto en su lugar:

while (true) {
  int ch = System.in.read();
  if ((ch < 0) || (ch == '\n'))
    break;
  if (!s.isFull())
    s.push((char) ch);
 }

Tenga en cuenta que no usamos demo aquí en absoluto, por lo que los problemas con su parámetro de tipo son irrelevantes.

Respondido 28 ago 11, 07:08

Tenga en cuenta que Character c; c = (int) 3; de hecho está definido y funciona perfectamente bien. Sin embargo, el resto de lo que dice es sólido, especialmente acerca de los peligros de empaquetar automáticamente el resultado de read () en un Character. - Ernest Friedman-Hill

@Ernest Friedman-Hill: Eso es interesante, no me di cuenta de eso y todavía no entiendo completamente lo que está sucediendo allí. Parece que esa asignación solo funciona si el int rvalue se puede determinar estáticamente para encajar en un char sin estrechar. Por ejemplo, c = (int) -1 y c = (int) 65536 No funcionan. Además, el análisis es local; int i = 3; c = i; no funciona en este caso. ¿Sabe dónde se cubre esto en el JLS? - erickson

Creo que esto está cubierto en la discusión de la sección 5.2, Conversión de asignación: "Se puede utilizar una conversión primitiva de restricción si el tipo de variable es byte, short o char, y el valor de la expresión constante se puede representar en el tipo de variable."- Ernest Friedman-Hill

@Ernest: ¡Eso definitivamente lo cubre! Gracias por la referencia. - erickson

SampleStack.ch es de tipo E. E es un objeto especificado por sus parámetros de tipo. Como no especificó un parámetro de tipo, el compilador coloca Object en para ti. Si querías ch a ser un Character, querrías SampleStack<Character> demo = new SampleStack<Character>(); o en Java 7 SampleStack<Character> demo = new SampleStack<>();.

Respondido 27 ago 11, 20:08

No ha proporcionado un parámetro de tipo cuando crea una instancia SampleStack, asi que demo.ch es de tipo Object. Eso obviamente no se puede comparar (o asignar, que es lo que sospecho que realmente querías hacer, de todos modos) de la int procedente de System.in.

Respondido 27 ago 11, 20:08

Tiene == (prueba de igualdad) cuando quieras = (asignación). En realidad, nunca estás asignando a demo.ch. La prueba de igualdad devuelve boolean, en lugar de char, de ahí el mensaje de error.

También necesitará emitir el resultado de System.in.read() a un carácter de un entero (o de lo contrario use SampleStack<Integer>, o algo así.)

Respondido 27 ago 11, 20:08

Bueno, el casting es una opción, pero hay mejores opciones, como la clase Scanner. - Mateusz Dymczyk

Tienes varios errores en este código:

  • como la gente señaló, estás creando una clase genérica pero no la estás generalizando y usándola sin formato, necesitas:

    SampleStack<Character>

  • incluso si lo cambia, no se ejecutará como tiene == en lugar de =

  • incluso si cambia los dos anteriores, no funcionará ya que System.in.read () devuelve un int, no un carácter, necesitaría hacer una pila de enteros O leer el valor de la entrada a una variable y luego lanzar pero no es una buena práctica. Usaría un escáner o algo similar para leer lo que el usuario ingresa de esta manera:

    Scanner sc = new Scanner(System.in); char c = sc.nextChar();

Respondido 27 ago 11, 20:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.