What I tried when I wanted to get all the fields of a bean

Keep a reminder of the process of trial and error to get all the fields in the bean.

Thing you want to do

I want to get all the fields in the bean with Iterator. ** "Field1, Field2, Field3, Field4" ** can be acquired for the following beans.

Fields.java


public class Fields {
  
  //field
  private String Field1;
  private String Field2;
  private String Field3;
  private String Field4;
  //constructor
  Fields(String Field1, String Field2, String Field3, String Field4) {
    this.Field1 = Field1;
    this.Field2 = Field2;
    this.Field3 = Field3;
    this.Field4 = Field4;
  }
  // settet,getter omitted
  // .
  // .
  // .
}

What I tried 1

Obtained using ** PropertyUtils / BeanUtils class ** of ** "Apache Commons" ** which is an external library of Java

** PropertyUtils ** and ** BeanUtils ** are classes that handle ** JavaBeans **. [^ 1] Among them, using the describe (Object bean) method that converts each value in the bean to Map and returns it, ** Convert Bean to Map → Get key value of converted Map (field name) ** I decided to get all the fields in the bean.

[^ 1]: Click here for a reference site on how to use BeanUtils. Java BeanUtils memo (Hishidama's commons-BeanUtils Memo)

Method

Fields.java(Use PropertyUtils)


 // PropertyUtils#Get all fields using describe
 public Iterator<?> getNames() 
		  throws IllegalAccessException, InvocationTargetException, NoSuchMethodException{
    try{
        //Convert Bean to Map → Get key value of converted Map (field name)
        return PropertyUtils.describe(this).keySet().iterator();
    }catch(IllegalAccessException e){
    	throw e;
    }catch(InvocationTargetException e){
    	throw e;
    }catch(NoSuchMethodException e){
    	throw e;
    }
  }

Fields.java(Use BeanUtils)


  // BeanUtilsUtils#Get all fields using describe
  public Iterator<?> getNames1() 
		  throws IllegalAccessException, InvocationTargetException, NoSuchMethodException{
	    try{
            //Convert Bean to Map → Get key value of converted Map (field name)
	        return BeanUtils.describe(this).keySet().iterator();
	    }catch(IllegalAccessException e){
	    	throw e;
	    }catch(InvocationTargetException e){
	    	throw e;
	    }catch(NoSuchMethodException e){
	    	throw e;
	    }
	  }

Execution class

FieldGet.java


package test;

import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;

public class FieldGet {
  public static void main (String args[]){

    Fields field = new Fields("Field 1","Field 2","Field 3","Field 4");
    Iterator<?> propertyUtils;
    Iterator<?> beanUtils;
	try {
		// PropertyUtils#Get all fields using describe
		propertyUtils = field.getNames();
		// BeanUtilsUtils#Get all fields using describe
		beanUtils = field.getNames1();
		System.out.println("--Use PropertyUtils--");
	    while(propertyUtils.hasNext()){
	        System.out.println(propertyUtils.next());
	    }
		System.out.println("--Using BeanUtils--");
	    while(beanUtils.hasNext()){
	        System.out.println(beanUtils.next());
	    }
	} catch (IllegalAccessException e) {
		e.printStackTrace();
	} catch (InvocationTargetException e) {
		e.printStackTrace();
	} catch (NoSuchMethodException e) {
		e.printStackTrace();
    }
  }
}

Execution result

Execution result


--Use PropertyUtils--
Field1
Field3
class
Field2
Field4
--Using BeanUtils--
Field1
Field3
class
Field2
Field4

I was able to get the field name of the bean, There seems to be room for improvement, such as getting a "class" that is not a field name, or not in ascending order.

Also, while running it several times ... ʻInvocationTargetException occurred at PropertyUtils / BeanUtils.describe (this) `, and the field could not be retrieved. I don't know the exact cause, so I decided to consider getting the field name in another way.

Execution result(part)


Caused by: java.lang.reflect.InvocationTargetException
	... 1024 more
Caused by: java.lang.StackOverflowError

What I tried 2

Use reflection

Bean fields can also be obtained ** with the reflection API **. [^ 2] With getDeclaredFields (), ** all access modifier (public, protected, default, private) fields can be retrieved as an array of Field class **.

[^ 2]: Get field with Java reflection API

Method

Fields.java(Use reflection)


  // Class#Get all fields using getDeclaredFields
  public Iterator<?> getNames2(){
        //Get fields for all access modifiers
    	Field[] tmpField = this.getClass().getDeclaredFields();
        //Generate a list to return with Iterator
    	List<String> Field = new ArrayList<String>();
    	for(int i = 0; i < tmpField.length; i++) {
            // getName()Get the field with
    		Field.add(tmpField[i].getName());
    	}
    	return Field.iterator();
    }

Execution class

FieldGet.java


package test;

import java.util.Iterator;

public class FieldGet {
  public static void main (String args[]){

    Fields field = new Fields("Field 1","Field 2","Field 3","Field 4");
    terator<?> reflection;
    // Class#Get all fields using getDeclaredFields
    reflection = field.getNames2();
    System.out.println("--Use reflection--");
    while(propertyUtils.hasNext()){
        System.out.println(propertyUtils.next());
    }
  }
}

Execution result

Execution result


--Use reflection--
Field1
Field2
Field3
Field4

Now, as expected, we were able to get all the fields.

Extra edition

Get all fields in Struts DynaActionForm

You can also get all fields in Struts DynaActionForm. ** ✳︎ The idea is the same as "What I tried 1" **

Step 1: Create a class that inherits DynaValidatorForm or DynaActionForm Step 2: Implement the method with the same idea ** as "What I tried 1" ** (Convert form to Map → Get key value of converted Map (field name)) **   Struts DynaActionForm has a getMap () method that converts the property defined in DynaActionForm to Map type and returns it **, so if you use that method, it is the same as "What I saw 1" It is possible to get all fields with the idea of. Is it something like ** equivalent to the describe (Object bean) method of the PropertyUtils / BeanUtils class **? I'm not sure about the detailed internal processing ...

StrutsDynaValidatorForm.java


package test;

import java.util.Iterator;
import org.apache.struts.validator.DynaValidatorForm;

public class StrutsDynaValidatorForm extends DynaValidatorForm {
	public Iterator getNames() {		
		return this.getMap().keySet().iterator();		
	}
}

Recommended Posts

What I tried when I wanted to get all the fields of a bean
I managed to get a blank when I brought the contents of Beans to the textarea
After all I wanted to preview the contents of mysql with Docker ...
I want to recursively get the superclass and interface of a certain class
Introducing what I made when I wanted to add a header and footer to RecyclerView
I tried what I wanted to try with Stream softly.
I tried to summarize the state transition of docker
I tried to decorate the simple calendar a little
05. I tried to stub the source of Spring Boot
I tried to reduce the capacity of Spring Boot
I tried to create a log reproduction script at the time of apt install
What I was addicted to when introducing the JNI library
I tried to summarize the basics of kotlin and java
[Swift] I tried to implement the function of the vending machine
I tried JAX-RS and made a note of the procedure
I tried to summarize the basic grammar of Ruby briefly
I tried to build the environment of WSL2 + Docker + VSCode
I tried to make a client of RESAS-API in Java
[jsoup] How to get the full amount of a document
When I switched to IntelliJ, I got a lot of differences in the encoding of the properties file.
I tried to make the sample application into a microservice according to the idea of the book "Microservice Architecture".
I want to get a list of the contents of a zip file and its uncompressed size
I tried to explain the method
The story I wanted to unzip
I tried to summarize what was asked at the site-java edition-
I tried to illuminate the Christmas tree in a life game
I tried to build the environment of PlantUML Server with Docker
I get a Ruby version error when I try to start Rails.
I tried to translate the error message when executing Eclipse (Java)
I made a gem to post the text of org-mode to qiita
I tried to check the operation of gRPC server with grpcurl
I tried to summarize the methods of Java String and StringBuilder
[Java] I tried to make a maze by the digging method ♪
I made a tool to output the difference of CSV file
I tried to solve the problem of Google Tech Dev Guide
What I was addicted to when updating the PHP version of the development environment (Docker) from 7.2.11 to 7.4.x
I tried to express the result of before and after of Date class with a number line
I tried to take a look at the flow of Android development environment construction with Android Studio
I tried to make a parent class of a value object in Ruby
A memo when you want to clear the time part of the calendar
I tried to summarize the methods used
Memorandum: What I was addicted to when I hit the accounting freee API
I tried to summarize the stumbling points when developing an Android application
A story I was addicted to when testing the API using MockMVC
A story that I wanted to write a process equivalent to a while statement with the Stream API of Java8
I tried to get started with WebAssembly
What to do when a javax.el.PropertyNotWritableException occurs
I want to know the JSP of the open portlet when developing Liferay
I tried to summarize the key points of gRPC design and development
It was a life I wanted to reset the thread-safe associative counter
I wanted to add @VisibleForTesting to the method
I tried to implement the Iterator pattern
[Java] How to get to the front of a specific string using the String class
I tried to summarize the Stream API
I want to get the IP address when connecting to Wi-Fi in Java
I tried to make full use of the CPU core in Ruby
I tried to visualize the access of Lambda → Athena with AWS X-Ray
How to get the absolute path of a directory running in Java
What is Docker? I tried to summarize
I want to get the field name of the [Java] field. (Old tale tone)
I tried to measure and compare the speed of GraalVM with JMH