ClassCastException error trying to cast between classes

2

I'm having trouble casting a class in a class, when I use the inherited class method it gives the following error:

  

"entity.Aula can not be cast to tableview.AulaTV"

Here is the exception described above.

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

Here are 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;
    }
}

Class AulaTV:

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
}
    
asked by anonymous 26.10.2016 / 13:14

2 answers

4

You are trying to cast the Aula class as if it were AulaTV , because the buscaAulaPorCodigo method returns a Aula type.

You can not convert a supertype (in this case the class Aula ) into a subtype (in this case, AulaTV ) by direct casting, the compiler can not guarantee this compatibility, so it pops up the exception. You can read more about DownCasting and UpCasting in this answer a>.

Change the return of this method, if you expect to return a type AulaTV , also ensure that the new AulaDAO().buscarPorCodigo(codigo); method 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 not change the method signature, another alternative way to check this conversion is to use instanceof , if you are sure that the return will be exactly a AulaTV type, even though it is marked as your supertype Aula , see an example (for demonstration purposes, of course):

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

if (aula instanceof AulaTV) {
   atv = aula;
}
    
26.10.2016 / 13:24
0

In fact we can yes downcast. If it were not possible the cast would not be defined in the language. But in your case the object you're casting on does not match the type of variable you want to store.

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

This is clearer to see in situations where we have a class hierarchy where the highest level class is abstract because there you can not new in it. A good example (but only to understand the theory, 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 the following:

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 a face error because the object is of superclass type different from the example I gave here.

Now, aside from all this, the idea of using inheritance you thought is not the best way to use this language feature (though some people will argue that it should never be used, but that's another conversation) . It seems that AulaTV is a class that takes care of aspects related to the screen, even the search methods of the Aula class could (should?) Be in a third class that only deals with aspects related to data access, wherever it is, in a database or other repository.

    
28.03.2018 / 11:20