Get all private fields java reflection

Java reflection get all private fields

It is possible to obtain all fields with the method getDeclaredFields() of Class . Then you have to check the modifier of each fields to find the private ones:

List privateFields = new ArrayList<>(); Field[] allFields = SomeClass.class.getDeclaredFields(); for (Field field : allFields) < if (Modifier.isPrivate(field.getModifiers())) < privateFields.add(field); >> 

Note that getDeclaredFields() will not return inherited fields.

Eventually, you get the type of the fields with the method Field.getType().

Solution 2

You can use Modifier to determine if a field is private. Be sure to use the getDeclaredFields method to ensure that you retrieve private fields from the class, calling getFields will only return the public fields.

public class SomeClass < private String aaa; private Date date; private double ccc; public int notPrivate; public static void main(String[] args) < Listfields = getPrivateFields(SomeClass.class); for(Field field: fields) < System.out.println(field.getName()); >> public static List getPrivateFields(Class theClass) < ListprivateFields = new ArrayList(); Field[] fields = theClass.getDeclaredFields(); for(Field field:fields) < if(Modifier.isPrivate(field.getModifiers()))< privateFields.add(field); >> return privateFields; > > 

Solution 3

Try FieldUtils from apache commons-lang3:

FieldUtils.getAllFieldsList(Class cls) 

Solution 4

Field[] fields = String.class.getDeclaredFields(); List privateFieldList = Arrays.asList(fields).stream().filter(field -> Modifier.isPrivate(field.getModifiers())).collect( Collectors.toList()); 

Solution 5

Check if a Field is private

You could filter the Fields using Modifier.isPrivate:

import java.lang.reflect.Field; import java.lang.reflect.Modifier; // . Field field = null; // retrieve the field in some way // . Modifier.isPrivate(field.getModifiers()) 

on a single Field object which returns true if the field is private

Collect all Fields of a class

To collect the all the Fields use:

1) If you need only the fields of the the class without the fields taken from the class hierarchy you could simply use:

Field[] fields = SomeClass.class.getDeclaredFields(); 

2) If you don’t want to reinvent the wheel and get all the fields of a class hierarchy you could rely upon Apache Commons Lang version 3.2+ which provides FieldUtils.getAllFieldsList :

import java.lang.reflect.Field; import java.util.AbstractCollection; import java.util.AbstractList; import java.util.AbstractSequentialList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import org.apache.commons.lang3.reflect.FieldUtils; import org.junit.Assert; import org.junit.Test; public class FieldUtilsTest < @Test public void testGetAllFieldsList() < // Get all fields in this class and all of its parents final ListallFields = FieldUtils.getAllFieldsList(LinkedList.class); // Get the fields form each individual class in the type's hierarchy final List allFieldsClass = Arrays.asList(LinkedList.class.getFields()); final List allFieldsParent = Arrays.asList(AbstractSequentialList.class.getFields()); final List allFieldsParentsParent = Arrays.asList(AbstractList.class.getFields()); final List allFieldsParentsParentsParent = Arrays.asList(AbstractCollection.class.getFields()); // Test that `getAllFieldsList` did truly get all of the fields of the the class and all its parents Assert.assertTrue(allFields.containsAll(allFieldsClass)); Assert.assertTrue(allFields.containsAll(allFieldsParent)); Assert.assertTrue(allFields.containsAll(allFieldsParentsParent)); Assert.assertTrue(allFields.containsAll(allFieldsParentsParentsParent)); > > 

Источник

Retrieve Fields from a Java Class Using Reflection

announcement - icon

As always, the writeup is super practical and based on a simple application that can work with documents with a mix of encrypted and unencrypted fields.

Читайте также:  Java import static java lang math

We rely on other people’s code in our own work. Every day.

It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production — debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky.

Lightrun is a new kind of debugger.

It’s one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics.

Learn more in this quick, 5-minute Lightrun tutorial:

announcement - icon

Slow MySQL query performance is all too common. Of course it is. A good way to go is, naturally, a dedicated profiler that actually understands the ins and outs of MySQL.

The Jet Profiler was built for MySQL only, so it can do things like real-time query performance, focus on most used tables or most frequent queries, quickly identify performance issues and basically help you optimize your queries.

Critically, it has very minimal impact on your server’s performance, with most of the profiling work done separately — so it needs no server changes, agents or separate services.

Basically, you install the desktop application, connect to your MySQL server, hit the record button, and you’ll have results within minutes:

announcement - icon

DbSchema is a super-flexible database designer, which can take you from designing the DB with your team all the way to safely deploying the schema.

The way it does all of that is by using a design model, a database-independent image of the schema, which can be shared in a team using GIT and compared or deployed on to any database.

And, of course, it can be heavily visual, allowing you to interact with the database using diagrams, visually compose queries, explore the data, generate random data, import data or build HTML5 database reports.

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

> CHECK OUT THE COURSE

1. Overview

Reflection is the ability for computer software to inspect its structure at runtime. In Java, we achieve this by using the Java Reflection API. It allows us to inspect the elements of a class such as fields, methods or even inner classes, all at runtime.

This tutorial will focus on how to retrieve the fields of a Java class, including private and inherited fields.

2. Retrieving Fields from a Class

Let’s first have a look at how to retrieve the fields of a class, regardless of their visibility. Later on, we’ll see how to get inherited fields as well.

Let’s start with an example of a Person class with two String fields: lastName and firstName. The former is protected (that’ll be useful later) while the latter is private:

We want to get both lastName and firstName fields using reflection. We’ll achieve this by using the Class::getDeclaredFields method. As its name suggests, this returns all the declared fields of a class, in the form of a Field array:

public class PersonAndEmployeeReflectionUnitTest < /* . constants . */ @Test public void givenPersonClass_whenGetDeclaredFields_thenTwoFields() < Field[] allFields = Person.class.getDeclaredFields(); assertEquals(2, allFields.length); assertTrue(Arrays.stream(allFields).anyMatch(field ->field.getName().equals(LAST_NAME_FIELD) && field.getType().equals(String.class)) ); assertTrue(Arrays.stream(allFields).anyMatch(field -> field.getName().equals(FIRST_NAME_FIELD) && field.getType().equals(String.class)) ); > >

As we can see, we get the two fields of the Person class. We check their names and types which matches the fields definitions in the Person class.

Читайте также:  calculate difference between two dates in year javascript

3. Retrieving Inherited Fields

Let’s now see how to get the inherited fields of a Java class.

To illustrate this, let’s create a second class named Employee extending Person, with a field of its own:

public class Employee extends Person

3.1. Retrieving Inherited Fields on a Simple Class Hierarchy

Using Employee.class.getDeclaredFields() would only return the employeeId field, as this method doesn’t return the fields declared in superclasses. To also get inherited fields we must also get the fields of the Person superclass.

Of course, we could use the getDeclaredFields() method on both Person and Employee classes and merge their results into a single array. But what if we don’t want to explicitly specify the superclass?

In this case, we can make use of another method of the Java Reflection API: Class::getSuperclass. This gives us the superclass of another class, without us needing to know what that superclass is.

Let’s gather the results of getDeclaredFields() on Employee.class and Employee.class.getSuperclass() and merge them into a single array:

@Test public void givenEmployeeClass_whenGetDeclaredFieldsOnBothClasses_thenThreeFields() < Field[] personFields = Employee.class.getSuperclass().getDeclaredFields(); Field[] employeeFields = Employee.class.getDeclaredFields(); Field[] allFields = new Field[employeeFields.length + personFields.length]; Arrays.setAll(allFields, i ->(i

We can see here that we’ve gathered the two fields of Person as well as the single field of Employee.

But, is the private field of Person really an inherited field? Not so much. That would be the same for a package-private field. Only public and protected fields are considered inherited.

3.2. Filtering public and protected Fields

Unfortunately, no method in the Java API allows us to gather public and protected fields from a class and its superclasses. The Class::getFields method approaches our goal as it returns all public fields of a class and its superclasses, but not the protected ones.

The only way we have to get only inherited fields is to use the getDeclaredFields() method, as we just did, and filter its results using the Field::getModifiers method. This one returns an int representing the modifiers of the current field. Each possible modifier is assigned a power of two between 2^0 and 2^7.

For example, public is 2^0 and static is 2^3. Therefore calling the getModifiers() method on a public and static field would return 9.

Then, it’s possible to perform a bitwise and between this value and the value of a specific modifier to see if that field has that modifier. If the operation returns something else than 0 then the modifier is applied, otherwise not.

We’re lucky as Java provides us with a utility class to check if modifiers are present in the value returned by getModifiers(). Let’s use the isPublic() and isProtected() methods to gather only inherited fields in our example:

List personFields = Arrays.stream(Employee.class.getSuperclass().getDeclaredFields()) .filter(f -> Modifier.isPublic(f.getModifiers()) || Modifier.isProtected(f.getModifiers())) .collect(Collectors.toList()); assertEquals(1, personFields.size()); assertTrue(personFields.stream().anyMatch(field -> field.getName().equals(LAST_NAME_FIELD) && field.getType().equals(String.class)) );

As we can see, the result doesn’t carry the private field anymore.

Читайте также:  Объединение ячеек

3.3. Retrieving Inherited Fields on a Deep Class Hierarchy

In the above example, we worked on a single class hierarchy. What do we do now if we have a deeper class hierarchy and want to gather all the inherited fields?

Let’s assume we have a subclass of Employee or a superclass of Person – then obtaining the fields of the whole hierarchy will require to check all the superclasses.

We can achieve that by creating a utility method that runs through the hierarchy, building the complete result for us:

List getAllFields(Class clazz) < if (clazz == null) < return Collections.emptyList(); >List result = new ArrayList<>(getAllFields(clazz.getSuperclass())); List filteredFields = Arrays.stream(clazz.getDeclaredFields()) .filter(f -> Modifier.isPublic(f.getModifiers()) || Modifier.isProtected(f.getModifiers())) .collect(Collectors.toList()); result.addAll(filteredFields); return result; >

This recursive method will search public and protected fields through the class hierarchy and returns all that have been found in a List.

Let’s illustrate it with a little test on a new MonthEmployee class, extending the Employee one:

public class MonthEmployee extends Employee

This class defines a new field – reward. Given all the hierarchy class, our method should give us the following fields definitions: Person::lastName, Employee::employeeId and MonthEmployee::reward.

Let’s call the getAllFields() method on MonthEmployee:

@Test public void givenMonthEmployeeClass_whenGetAllFields_thenThreeFields() < ListallFields = getAllFields(MonthEmployee.class); assertEquals(3, allFields.size()); assertTrue(allFields.stream().anyMatch(field -> field.getName().equals(LAST_NAME_FIELD) && field.getType().equals(String.class)) ); assertTrue(allFields.stream().anyMatch(field -> field.getName().equals(EMPLOYEE_ID_FIELD) && field.getType().equals(int.class)) ); assertTrue(allFields.stream().anyMatch(field -> field.getName().equals(MONTH_EMPLOYEE_REWARD_FIELD) && field.getType().equals(double.class)) ); >

As expected, we gather all the public and protected fields.

4. Conclusion

In this article, we saw how to retrieve the fields of a Java class using the Java Reflection API.

We first learned how to retrieve the declared fields of a class. After that, we saw how to retrieve its superclass fields as well. Then, we learned to filter out non-public and non-protected fields.

Finally, we saw how to apply all of this to gather the inherited fields of a multiple class hierarchy.

As usual, the full code for this article is available over on our GitHub.

announcement - icon

Slow MySQL query performance is all too common. Of course it is. A good way to go is, naturally, a dedicated profiler that actually understands the ins and outs of MySQL.

The Jet Profiler was built for MySQL only, so it can do things like real-time query performance, focus on most used tables or most frequent queries, quickly identify performance issues and basically help you optimize your queries.

Critically, it has very minimal impact on your server’s performance, with most of the profiling work done separately — so it needs no server changes, agents or separate services.

Basically, you install the desktop application, connect to your MySQL server, hit the record button, and you’ll have results within minutes:

Источник

Оцените статью