Problems with cast in reflection

-1

Good afternoon. I'm new to using the reflection java API. I am having the following problem, when trying to create a generic Dao class to be used in a CRUD to sqlite in android, I can not cast a field of the corresponding type in the object class passed as input parameter. Here is the code:

public class DaoGenerico<E>{

    private E entrada;
    private Class classe;
    private SQLiteDatabase db;
    private List<Field> campos;
    private List<Method> metodos;
    private String banco;

    public DaoGenerico(E entrada, SQLiteDatabase db) {

        iniciaComponetes(entrada, db);

        if(!classe.isAnnotationPresent(TabelaNoBanco.class)) {
            throw new RuntimeException("Classe não pode ser persistida!");
        }

        TabelaNoBanco anotacao = (TabelaNoBanco) classe.getAnnotation(TabelaNoBanco.class);
        this.banco = anotacao.nomeTabela();

    }


    public boolean inserir() throws IllegalAccessException {
        try {
            ContentValues values = new ContentValues();

            for (Field f : campos) {
                f.setAccessible(true);
                Class<?> type = f.getType();

                /*Linha onde deve ser efetuado o cast, porem apresenta erro em type*/
                values.put(f.getName(), (type) f.get(entrada));

            }
            db.insert(banco, null, values);
            db.close();
            return true;
        }catch(ClassCastException e){
            throw new RuntimeException("Campo não pode ser convertido");
        } catch (Exception e){
            throw new RuntimeException("Não foi possivel inserir  objeto no banco de dados!");
        }
    }

    private List<Field> obterCampos(){
        return Arrays.asList(classe.getFields());
    }

    private List<Method> obterMetodos(){
        return Arrays.asList(classe.getDeclaredMethods());
    }

    private void iniciaComponetes(E entrada, SQLiteDatabase db) {
        this.entrada = entrada;
        this.db = db;
        this.classe = entrada.getClass();
        this.campos = obterCampos();
        this.metodos = obterMetodos();
    }
}
    
asked by anonymous 24.11.2016 / 16:34

1 answer

1

First this line:

private Class classe;

It could be:

private Class<? extends E> classe;

Then we see that your inserir method closes the db object, but it did not open it. As a good practice, usually the responsibility of closing is from who opened it. And if the inserir method always returns true , then what would be the purpose of the return type?

Your problem occurs in these lines:

                Class<?> type = f.getType();

                /*Linha onde deve ser efetuado o cast, porem apresenta erro em type*/
                values.put(f.getName(), (type) f.get(entrada));

What's wrong? Is that to make a cast you must use open-brackets + class-name + close-parentheses. It happens that type is not a class name, but a variable name. Therefore, the compiler does not recognize cast and gives compilation error.

So how do? It could be with this awful thing:

Object obj = f.get(entrada);
if (obj == null) {
    values.putNull(f.getName());
} else if (obj instanceof String) {
    values.put(f.getName(), (String) obj);
} else if (obj instanceof Boolean) {
    values.put(f.getName(), (Boolean) obj);
} else if (obj instanceof Byte) {
    values.put(f.getName(), (Byte) obj);
} else if (obj instanceof Short) {
    values.put(f.getName(), (Short) obj);
} else if (obj instanceof Integer) {
    values.put(f.getName(), (Integer) obj);
} else if (obj instanceof Long) {
    values.put(f.getName(), (Long) obj);
} else if (obj instanceof Float) {
    values.put(f.getName(), (Float) obj);
} else if (obj instanceof Double) {
    values.put(f.getName(), (Double) obj);
} else if (obj instanceof Short) {
    values.put(f.getName(), (Short) obj);
} else if (obj instanceof byte[]) {
    values.put(f.getName(), (byte[]) obj);
} else {
    throw new ClassCastException("Campo não pode ser convertido.");
}

Or if you want to use reflection here too:

Object obj = f.get(entrada);
if (obj == null) {
    values.putNull(f.getName());
} else {
    Method m;
    try {
        m = ContentValues.class.getMethod("put", String.class, obj.getClass());
        m.invoke(values, f.getName(), obj);
    } catch (NoSuchMethodException e) {
        throw new ClassCastException("Campo não pode ser convertido.", e);
    } catch (InvocationTargetException e) {
        throw new AssertionError(e.getCause());
    }
}

Oh, and do not forget to use campo.setAccessible(true) and metodo.setAccessible(true) where applicable. Otherwise, you can take a IllegalAccessException .

    
24.11.2016 / 16:56