Home > database >  How can I get class members of a generic class?
How can I get class members of a generic class?

Time:04-07

How can I get class members of a generic class?

The result of findAll of Entity of type T is entered as a parameter.

findAll is:

findAll = {ArrayList@11389} size = 1
 0 = {Account@11395}
  id = {Long@14680} 1
  userid = "test"
  username = "username"
  password = "{bcrypt}$2a$10$n.BVxjdvW.C8jBPmZ6U.Ueldc2zb5JZud5U2zH0HaN6Pu0lcjndiK"
  role = {AccountRole@14684} "USER"

At this time, you need to get all the values ​​of id, userid, username, and password, which are the results of findAll, but you cannot do getId, getUserid, getUsername, getPassword, etc. because it is a generic class with T.

In this case, I wonder how I can get all class members in class T.

Below is my code.

public void entityToExcel(List<T> findAll) {
            List<String> headers = createHeader();


            // create worksheet
            XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = workbook.createSheet("proper sheetname");
            int rowNumber = 0;

            // create header
            XSSFRow headerRow = sheet.createRow(rowNumber  );
            for (int i = 0; i < headers.size(); i  ) {
                headerRow.createCell(i).setCellValue(headers.get(i));
                System.out.println("headers.get(i) = "   headers.get(i));
            }

            //Enter entity data line by line
            XSSFRow row = sheet.createRow(rowNumber  );

            for (int i = 0; i < findAll.size(); i  ) {
                T find = findAll.get(i);
                find.getId(); ?? //cannot resolve method `getId` in `T` error
//I have to work here row.createCell(i).setCellValue(find.getEachClassVariable);
            }

        }

CodePudding user response:

The properties of T find can be accessed by casting.

Account account = (Account) find;
account.getId()

But if the entityToExcel function only accepts Account list, why not just declare the function as

public void entityToExcel(List<Account > findAll)

Or interface-oriented programming


public class ExcelService {

    public <T extends IEntity> void entityToExcel(List<T> findAll) {
        for (int i = 0; i < findAll.size(); i  ) {
            T find = findAll.get(i);
            System.out.println(find.getId());
            System.out.println(find.getUsername());
        }
    }

    interface IEntity {
        String getId();

        String getUsername();
    }

    static class Account implements IEntity {
        private String id;
        private String name;

        @Override
        public String getId() {
            return this.id;
        }

        @Override
        public String getUsername() {
            return this.name;
        }
    }
}

CodePudding user response:

I recently had this problem when working with generics. The solution that I found was relatively simple. First make sure that all classes that you are passing in is a subclass of some superclass. Let's define that superclass as Resource. We will then call a method named getAllFields which will get all of the fields of that class. The method will take a type E which extends Resource. We will then create a new instance of the class being passed in and set it to a Resource with (Resource) Class.forName(type.getName()).getConstructor().newInstance(); This creates a new instance of the type with class.forName() and casts it to a Resource object.

This is what the method looks like so far:

 public <E extends Resource> E getAllFields(Class<E> type) {
        Resource res = (Resource) 
        Class.forName(type.getName()).getConstructor().newInstance();
    }

We can now iterate through each of the fields in the class with for (Field field : res.getClass().getDeclaredFields()) We can get the values of the fields with field.get(res) BUT first we have to make the field accessible with field.setAccessible(true);

Finally, to get all the methods in the class the reflective method getDeclaredMethods will return all the methods.

 public <E extends Resource> E getAllFields(Class<E> type) {
        Resource res = (Resource) 
        Class.forName(type.getName()).getConstructor().newInstance();

         for (Field field : res.getClass().getDeclaredFields()) {
           field.setAccessible(true);
           System.out.println(field.get(res));
         }
         
         for(Method method : res.getClass.getDeclaredMethods() {
           System.out.println(method.getName());
         }
  }
  • Related