Create a method that receives a generic class?

3

I've been breaking my head with the Reflection API. I'm writing a class (reader) that reads a CSV file and creates an ArrayList of objects based on CSV. I've done a test class to write the code, but I want to adapt the code so that it works with any class that is passed.

Principal.java (main)

import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;

public class Principal {

    public static void main(String[] args) {

        ArrayList<Object> listaDeObjetos;
        Leitor objetoDaClasseLeitor = new Leitor();

        Path caminho = Paths.get("/home/filipe/eclipse-workspace/ReadCSVFile/src", "a.csv");
        Charset codificacao = Charset.forName("UTF-8");
        String separador = ",";
        ClasseDeTeste classe;
        classe = new ClasseDeTeste();

        try {
            System.out.println(objetoDaClasseLeitor.leArquivo(caminho, codificacao, separador, classeCriada));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

Test Class.java

public class ClasseDeTeste {
    String id;
    String nome;
    String telefone;
    String email;

    public void setId(String id) {
        this.id = id;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public void setTelefone(String telefone) {
        this.telefone = telefone;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

Reader.java

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.format.TextStyle;
import java.util.ArrayList;
import java.util.List;

public class Leitor {

    List<String> linhas;
    String texto;
    ArrayList<Object> objetosCriados = new ArrayList<>();
    String[] colunas;
    Class<?> classePassada;
    ArrayList<Method>setters;

    ArrayList<Object> leArquivo(Path caminho, Charset codificacao, String separador, ClasseDeTeste classe) throws Exception {
        // Lê e processa o arquivo

        linhas = Files.readAllLines( caminho, codificacao );
        colunas = linhas.get(0).split(separador);

        //Crio um array para o nome dos setters
        String[] nomeDosSetters = new String[colunas.length];       

        //Transformo o nome das Colunas para um SetNome
        for(int i = 0; i < colunas.length; i ++){
            String nomeDoMetodo;
            nomeDoMetodo = ("set" + colunas[i].substring(0, 1).toUpperCase() +
                    colunas[i].substring(1).toLowerCase());

            nomeDosSetters[i] = nomeDoMetodo; 
        }

        //Crio uma nova instância com o nome da classe passada
        classePassada = classe.getClass();

        //Crio um Array de Objetos, será o array a ser retornado no final 
        for(int i = 1; i < linhas.size(); i++) {
            objetosCriados.add(classePassada.newInstance());
        }

        //Percorro as linhas (objetos) do csv
        for(int i = 1; i < linhas.size(); i++) {
            String[] valores = linhas.get(i).split(separador);

            //Percorro os valores de cada linha (objeto) do csv
            for(int j = 0; j < valores.length; j++) {
                Method setter2 = classePassada.getMethod(nomeDosSetters[j], String.class);
                setter2.invoke(objetosCriados.get(i-1), valores[j]);
            }
        }

        return objetosCriados;
    }



}

I want my method leArquivo to accept any past class, and for that it looks like:

ArrayList<Object> leArquivo(Path caminho, Charset codificacao, String separador, **Class<?> classe**) throws Exception {
    }

It happens that when I move from

ClasseDeTeste classe

for

Class<?> classe

My main file stops working and I can not resolve it. Any idea what might be happening?

    
asked by anonymous 07.06.2018 / 17:03

1 answer

1

If I understand you, you do not need a Class<?> classe property in your Leitor class. Just use in your logic the class entered in the parameter itself of the leArquivo(...) method.

So:

1) The signature of your method should be:

ArrayList<Object> leArquivo(Path caminho, Charset codificacao, String separador, Class<?> classe) throws Exception

2) In your logic in the Leitor class, for example, in this section:

//Crio um Array de Objetos, será o array a ser retornado no final 
for(int i = 1; i < linhas.size(); i++) {
     objetosCriados.add(classePassada.newInstance());
}

You go instead of using classePassada.newInstance() , use classe (that came from the parameter) and follow with your logic.

More simple example:

class Leitor {
    void exibirInfosDaClasse(Class<?> clazz){
        //uso direto clazz, não tenho necessidade de ter uma propriedade dentro da classe
        System.out.println(clazz.getName());
        System.out.println(Arrays.toString(clazz.getMethods()));
    }
}

class ClasseQualquer {
    public void metodo1(){};
    public void metodo2(){};
}

public final static void main(String... args) throws Exception {
        Leitor leitor = new Leitor();
        leitor.exibirInfosDaClasse(ClasseQualquer.class);
//imprime
//ClasseQualquer
//[public void ClasseQualquer.metodo1(), public void ClasseQualquer.metodo2() etc...]
    }
}
    
07.06.2018 / 20:56