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;
}
}
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.