Classcastexception error when trying to cast between classes

Asked

Viewed 697 times

2

I have the problem to perform a "Cast" in a class, when using the inherited class method of the following error:

"entity. Aula cannot be cast to tableview.Aulatv"

Here gives the exception described above.

AulaTV atv = (AulaTV) new Aula().buscarPorCodigo("1ageoB2");

Follows the classes used:

public class Aula {

    private int id;
    private String codigo;
    private String titulo;
    private String conteudo;
    private Date dtCadastro;
    private String log;
    private int serie;
    private int disciplina;
    private int empresa;
    private int cliente;
    private File arq;

    public Aula() {
    }

    public Aula(int id, String codigo, String titulo, String conteudo, Date dtCadastro, String log, int serie, int disciplina, int empresa, int cliente, File arq) {
        this.id = id;
        this.codigo = codigo;
        this.titulo = titulo;
        this.conteudo = conteudo;
        this.dtCadastro = dtCadastro;
        this.log = log;
        this.serie = serie;
        this.disciplina = disciplina;
        this.empresa = empresa;
        this.cliente = cliente;
        this.arq = arq;
    }

    // gets and sets

    public Aula buscaAulaPorCodigo(String codigo) throws Exception {
        Aula aula = null;
        try {
            aula = new AulaDAO().buscarPorCodigo(codigo);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            throw new Exception(e.getLocalizedMessage());
        }
        return aula;
    }

    public static Aula buscaNoListPorNome(List<Aula> list, String chave) {
        for (Aula a : list) {
            if (a.getCodigo().equalsIgnoreCase(chave)) {
                return a;
            }
        }
        return null;
    }
}

Aulatv class:

public class AulaTV extends Aula {

    private CheckBox checkBox;

    public AulaTV() {
        super();
        checkBox = new CheckBox();
    }

    public AulaTV(CheckBox checkBox, int id, String codigo, String titulo, String conteudo, Date dtCadastro, String log, int serie, int disciplina, int empresa, int cliente, File arq) {
        super(id, codigo, titulo, conteudo, dtCadastro, log, serie, disciplina, empresa, cliente, arq);
        this.checkBox = checkBox;
    }

    // gets and sets
}
  • 1

    Abbreviate that code, that pile of get and set are unnecessary to understand the problem...

2 answers

4


You’re trying to cast the class Aula as if it were AulaTV, for the method buscaAulaPorCodigo returns a type Aula.

You cannot convert a supertype (in case the class Aula) in a subtype (in this case, AulaTV) by direct casting, the compiler has no way to guarantee this compatibility, so it bursts the exception. You can read more about Downcasting and Upcasting in this answer.

Change the return of this method if you expect to return a type AulaTV, also ensure that the new AulaDAO().buscarPorCodigo(codigo); will return an object of this type.

   public AulaTV buscaAulaPorCodigo(String codigo) throws Exception {
        Aula aula = null;
        try {
            aula = new AulaDAO().buscarPorCodigo(codigo);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            throw new Exception(e.getLocalizedMessage());
        }
        return aula;
    }

And remove the cast from the line:

AulaTV atv = new Aula().buscarPorCodigo("1ageoB2");

Or if you can’t change the method signature, another alternative way to check this conversion is by using the instanceof, if you are sure that the return will be exactly one type AulaTV, even if it’s flagged as your supertype Aula, see an example (for demonstration purposes only, of course):

Aula aula = new Aula().buscarPorCodigo("1ageoB2");
AulaTV atv;

if (aula instanceof AulaTV) {
   atv = aula;
}
  • In this case in all the rest of the code where I use the method "searchAulaPorCodigo(String code)" I will have an error, my intention to create an inheritance for this is precisely to be able to reuse the methods without having to rewrite the method.

  • @Luiscalegari only that the cast you are trying to do will always of the error. You cannot convert a supertype into a subtype, the compiler cannot guarantee this compatibility, so it bursts the exception. If it is not possible to change the signature of the method, then it will be necessary to reassess the need of the cast.

  • Thanks for the help... it was very clear to me the concept of Downcasting and Upcasting in the post you indicated... Still had no knowledge about these terms...

  • @Luiscalegari a suggestion, from what I saw of the implementation, you can separate the two classes, and create a common interface between them, this way it will be possible to call Aula where one expects AulaTv.

0

Actually we can yes downcast. If it was not possible the cast would not be set in the language. Only in your case the object in which you are applying the cast is not compatible with the type of variable in which you want to store.

First we need to separate two things, we have the type of the variable that references and the type of the object itself in memory. They can be different. The object type is defined by the class you use to do the new and in this case it was Class. This means for example that it does not have the structures of the Aulatv class and during execution the JVM can verify that the object does not have a type compatible with the target variable.

This becomes clearer to see in situations where we have a hierarchy of classes in which the highest class is abstract 'cause then you can’t do new in it. A good example (but just to understand the theory, it is not very practical in the sense of real day-to-day problems) is to consider a class hierarchy for polygons:

public abstract class Poligono { ... }

public class Triangulo extends Poligono { ... }

public class Retangulo extends Poligono { ... }

You can do things like follow them:

Poligono p = new Triangulo();
Triangulo t = (Triangulo) p; //Isso é um downcast válido

Retangulo r = new Retangulo();
p = r; //Upcast não precisa de cast, o compilador aceita.
r = (Retangulo) p; //Novamente downcast

p = t; //Upcast não precisa de cast, o compilador aceita.
r = (Retangulo) p; //Novamente downcast, erro em tempo de execução

In your case as the superclass is concrete you already have an error of face because the object is of the kind of superclass different from the example I gave here.

Now, part of all this, the idea of inheritance usage that you thought up is not the best way to use this language resource (although some people will argue that it should not even be used ever, but that’s another conversation). Apparently AulaTV is a class that takes care of screen-related aspects, including the class search methods Aula could (should?) be in a third class that only takes care of aspects related to data access, wherever it may be, in a database or other repository.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.