Try this
import java.lang.reflect.Field;
public class ToStringMaker {
public ToStringMaker( Object o) {
Class<? extends Object> c = o.getClass();
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
String name = field.getName();
field.setAccessible(true);
try {
System.out.format("%n%s: %s", name, field.get(o));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}}
Answer from mottaman85 on Stack OverflowYou should pass the object to get method of the field, so
import java.lang.reflect.Field;
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object value = field.get(object);
Like answered before, you should use:
Object value = field.get(objectInstance);
Another way, which is sometimes prefered, is calling the getter dynamically. example code:
public static Object runGetter(Field field, BaseValidationObject o)
{
// MZ: Find the correct method
for (Method method : o.getMethods())
{
if ((method.getName().startsWith("get")) && (method.getName().length() == (field.getName().length() + 3)))
{
if (method.getName().toLowerCase().endsWith(field.getName().toLowerCase()))
{
// MZ: Method found, run it
try
{
return method.invoke(o);
}
catch (IllegalAccessException e)
{
Logger.fatal("Could not determine method: " + method.getName());
}
catch (InvocationTargetException e)
{
Logger.fatal("Could not determine method: " + method.getName());
}
}
}
}
return null;
}
Also be aware that when your class inherits from another class, you need to recursively determine the Field. for instance, to fetch all Fields of a given class;
for (Class<?> c = someClass; c != null; c = c.getSuperclass())
{
Field[] fields = c.getDeclaredFields();
for (Field classField : fields)
{
result.add(classField);
}
}
Something like this...
import java.lang.reflect.Field;
public class Test {
public static void main(String... args) {
try {
Foobar foobar = new Foobar("Peter");
System.out.println("Name: " + foobar.getName());
Class<?> clazz = Class.forName("com.csa.mdm.Foobar");
System.out.println("Class: " + clazz);
Field field = clazz.getDeclaredField("name");
field.setAccessible(true);
String value = (String) field.get(foobar);
System.out.println("Value: " + value);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Foobar {
private final String name;
public Foobar(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
Or, you can use the newInstance method of class to get an instance of your object at runtime. You'll still need to set that instance variable first though, otherwise it won't have any value.
E.g.
Class<?> clazz = Class.forName("com.something.Foobar");
Object object = clazz.newInstance();
Or, where it has two parameters in its constructor, String and int for example...
Class<?> clazz = Class.forName("com.something.Foobar");
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("Meaning Of Life", 42);
Or you can interrogate it for its constructors at runtime using clazz.getConstructors()
NB I deliberately omitted the casting of the object created here to the kind expected, as that would defeat the point of the reflection, as you'd already be aware of the class if you do that, which would negate the need for reflection in the first place.
You can create instance from class object and that can be used in field get value.
Class modelClass = Class.forName("com.gati.stackoverflow.EX");
final Field field = modelClass.getDeclaredField("value");
field.setAccessible(true);
Object modelInstance=modelClass.newInstance();
field.get(modelInstance);
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<Field> 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().
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) {
List<Field> fields = getPrivateFields(SomeClass.class);
for(Field field: fields){
System.out.println(field.getName());
}
}
public static List<Field> getPrivateFields(Class<?> theClass){
List<Field> privateFields = new ArrayList<Field>();
Field[] fields = theClass.getDeclaredFields();
for(Field field:fields){
if(Modifier.isPrivate(field.getModifiers())){
privateFields.add(field);
}
}
return privateFields;
}
}
no, you need to write it yourself. It is a simple recursive method called on Class.getSuperClass():
public static List<Field> getAllFields(List<Field> fields, Class<?> type) {
fields.addAll(Arrays.asList(type.getDeclaredFields()));
if (type.getSuperclass() != null) {
getAllFields(fields, type.getSuperclass());
}
return fields;
}
@Test
public void getLinkedListFields() {
System.out.println(getAllFields(new LinkedList<Field>(), LinkedList.class));
}
public static List<Field> getAllFields(Class<?> type) {
List<Field> fields = new ArrayList<Field>();
for (Class<?> c = type; c != null; c = c.getSuperclass()) {
fields.addAll(Arrays.asList(c.getDeclaredFields()));
}
return fields;
}
You can use Class#getDeclaredFields() to get all declared fields of the class. You can use Field#get() to get the value.
In short:
Object someObject = getItSomehow();
for (Field field : someObject.getClass().getDeclaredFields()) {
field.setAccessible(true); // You might want to set modifier to public first.
Object value = field.get(someObject);
if (value != null) {
System.out.println(field.getName() + "=" + value);
}
}
To learn more about reflection, check the Oracle tutorial on the subject.
That said, if that VO is a fullworthy Javabean, then the fields do not necessarily represent real properties of a VO. You would rather like to determine the public methods starting with get or is and then invoke it to grab the real property values.
for (Method method : someObject.getClass().getDeclaredMethods()) {
if (Modifier.isPublic(method.getModifiers())
&& method.getParameterTypes().length == 0
&& method.getReturnType() != void.class
&& (method.getName().startsWith("get") || method.getName().startsWith("is"))
) {
Object value = method.invoke(someObject);
if (value != null) {
System.out.println(method.getName() + "=" + value);
}
}
}
That in turn said, there may be more elegant ways to solve your actual problem. If you elaborate a bit more about the functional requirement for which you think that this is the right solution, then we may be able to suggest the right solution. There are many, many tools available to massage javabeans. There's even a built-in one provided by Java SE in the java.beans package.
BeanInfo beanInfo = Introspector.getBeanInfo(someObject.getClass());
for (PropertyDescriptor property : beanInfo.getPropertyDescriptors()) {
Method getter = property.getReadMethod();
if (getter != null) {
Object value = getter.invoke(someObject);
if (value != null) {
System.out.println(property.getName() + "=" + value);
}
}
}
Here's a quick and dirty method that does what you want in a generic way. You'll need to add exception handling and you'll probably want to cache the BeanInfo types in a weakhashmap.
public Map<String, Object> getNonNullProperties(final Object thingy) {
final Map<String, Object> nonNullProperties = new TreeMap<String, Object>();
try {
final BeanInfo beanInfo = Introspector.getBeanInfo(thingy
.getClass());
for (final PropertyDescriptor descriptor : beanInfo
.getPropertyDescriptors()) {
try {
final Object propertyValue = descriptor.getReadMethod()
.invoke(thingy);
if (propertyValue != null) {
nonNullProperties.put(descriptor.getName(),
propertyValue);
}
} catch (final IllegalArgumentException e) {
// handle this please
} catch (final IllegalAccessException e) {
// and this also
} catch (final InvocationTargetException e) {
// and this, too
}
}
} catch (final IntrospectionException e) {
// do something sensible here
}
return nonNullProperties;
}
See these references:
- BeanInfo (JavaDoc)
- Introspector.getBeanInfo(class) (JavaDoc)
- Introspection (Sun Java Tutorial)
Use reflection to access the fields declared on the class. Then iterate through the fields and check to see if their type matches Image.
You could also create a more useful method by accepting two parameters a target Class and a searchType Class. The method would then searches for fields with the target of the type searchType.
I would also recommend making this method static, since it really doesn't depend on any of the classes state.
Example
public class Contact {
private String surname, lastname, address;
private int age, floor;
private Image contactPhoto, companyPhoto;
private boolean isEmployed;
public static String[] getFieldsOfType(Class<?> target, Class<?> searchType) {
Field[] fields = target.getDeclaredFields();
List<String> results = new LinkedList<String>();
for(Field f:fields){
if(f.getType().equals(searchType)){
results.add(f.getName());
}
}
return results.toArray(new String[results.size()]);
}
public static String[] getAllImages(){
return getFieldsOfType(Contact.class, Image.class);
}
public static void main(String[] args) {
String[] fieldNames = getAllImages();
for(String name:fieldNames){
System.out.println(name);
}
}
}
A simpler alternative to using reflection would be to use a map as the primary data type for the field you are interested in:
public class Contact {
private static final String CONTACT_PHOTO = "contactPhoto";
private static final String COMPANY_PHOTO = "companyPhoto";
private String surname, lastname, address;
private int age, floor;
private HashMap<String, Image> images;
private boolean isEmployed;
public Contact() {
images = new HashMap<String, Image>();
images.put(CONTACT_PHOTO, null);
images.put(COMPANY_PHOTO, null);
}
public String[] getAllImages() {
Set<String> imageNames = images.keySet();
return imageNames.toArray(new String[imageNames.size()]);
}
public void setContactPhoto(Image img) {
images.put(CONTACT_PHOTO, img);
}
public Image getContactPhoto() {
return images.get(CONTACT_PHOTO);
}
public void setCompanyPhoto(Image img) {
images.put(COMPANY_PHOTO, img);
}
public Image getCompanyPhoto() {
return images.get(COMPANY_PHOTO);
}
}
You can use the following method:
RecordComponent[] getRecordComponents()
You can retrieve name, type, generic type, annotations, and its accessor method from RecordComponent.
Point.java:
record Point(int x, int y) { }
RecordDemo.java:
import java.lang.reflect.RecordComponent;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class RecordDemo {
public static void main(String args[]) throws InvocationTargetException, IllegalAccessException {
Point point = new Point(10,20);
RecordComponent[] rc = Point.class.getRecordComponents();
System.out.println(rc[0].getAccessor().invoke(point));
}
}
Output:
10
Alternatively,
import java.lang.reflect.RecordComponent;
import java.lang.reflect.Field;
public class RecordDemo {
public static void main(String args[])
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException {
Point point = new Point(10, 20);
RecordComponent[] rc = Point.class.getRecordComponents();
Field field = Point.class.getDeclaredField(rc[0].getAccessor().getName());
field.setAccessible(true);
System.out.println(field.get(point));
}
}
Your class and record aren't equivalent: records have private fields.
Class#getFields() returns public fields only.
You could use Class#getDeclaredFields() instead.