Accessing a value of a string defined in a interface of constants - java

I have a constant interface file like so ->
public interface MyConstants {
String CONSTANT_ONE = "foo";
String CONSTANT_TWO = "hello";
}
How do I iterate over this to get the values of the constant? I saw a method using reflect where you can access it like this ->
Field[] interfaceFields = MyConstants.class.getFields();
for(Field f : interfaceFields) {
f.get(f.getName());
}
This returns an object but I want it to be of type String. I know I can typecast it but what's the correct way of doing this?

There are a couple of ways to make this safe, i.e. allow you to cast the Object values to Strings without getting a ClassCastException.
Use instanceOf to check the actual Class of the Object reference.
Check the type of the field before accessing it.
package org.example;
import java.lang.reflect.Field;
public class SO62746826 {
public interface MyConstants {
String CONSTANT_ONE = "foo";
String CONSTANT_TWO = "hello";
int CONSTANT_THREE = 1; // now we have this field casting each of the values will throw a ClassCastException on this one
}
public static void main(String... args) throws IllegalAccessException {
Field[] interfaceFields = MyConstants.class.getFields();
for(Field f : interfaceFields) {
Object o = f.get(null);
if (o instanceof String) {
String s = (String)o;
System.out.println(s);
}
// or
if (f.getType().equals(String.class)) {
String s = (String)f.get(null);
System.out.println(s);
}
}
}
}

Related

how to set value with reflection [duplicate]

I have 2 classes: Father and Child
public class Father implements Serializable, JSONInterface {
private String a_field;
//setter and getter here
}
public class Child extends Father {
//empty class
}
With reflection I want to set a_field in Child class:
Class<?> clazz = Class.forName("Child");
Object cc = clazz.newInstance();
Field f1 = cc.getClass().getField("a_field");
f1.set(cc, "reflecting on life");
String str1 = (String) f1.get(cc.getClass());
System.out.println("field: " + str1);
but I have an exception:
Exception in thread "main" java.lang.NoSuchFieldException: a_field
But if I try:
Child child = new Child();
child.setA_field("123");
it works.
Using setter method I have same problem:
method = cc.getClass().getMethod("setA_field");
method.invoke(cc, new Object[] { "aaaaaaaaaaaaaa" });
To access a private field you need to set Field::setAccessible to true. You can pull the field off the super class. This code works:
Class<?> clazz = Child.class;
Object cc = clazz.newInstance();
Field f1 = cc.getClass().getSuperclass().getDeclaredField("a_field");
f1.setAccessible(true);
f1.set(cc, "reflecting on life");
String str1 = (String) f1.get(cc);
System.out.println("field: " + str1);
Using FieldUtils from the Apache Commons Lang 3:
FieldUtils.writeField(childInstance, "a_field", "Hello", true);
The true forces it to set, even if the field is private.
Kotlin verison
Get private variable using below extension functions
fun <T : Any> T.getPrivateProperty(variableName: String): Any? {
return javaClass.getDeclaredField(variableName).let { field ->
field.isAccessible = true
return#let field.get(this)
}
}
Set private variable value get the variable
fun <T : Any> T.setAndReturnPrivateProperty(variableName: String, data: Any): Any? {
return javaClass.getDeclaredField(variableName).let { field ->
field.isAccessible = true
field.set(this, data)
return#let field.get(this)
}
}
Get variable use:
val bool = <your_class_object>.getPrivateProperty("your_variable") as String
Set and get variable use:
val bool = <your_class_object>.setAndReturnPrivateProperty("your_variable", true) as Boolean
val str = <your_class_object>.setAndReturnPrivateProperty("your_variable", "Hello") as String
Java version
public class RefUtil {
public static Field setFieldValue(Object object, String fieldName, Object valueTobeSet) throws NoSuchFieldException, IllegalAccessException {
Field field = getField(object.getClass(), fieldName);
field.setAccessible(true);
field.set(object, valueTobeSet);
return field;
}
public static Object getPrivateFieldValue(Object object, String fieldName) throws NoSuchFieldException, IllegalAccessException {
Field field = getField(object.getClass(), fieldName);
field.setAccessible(true);
return field.get(object);
}
private static Field getField(Class mClass, String fieldName) throws NoSuchFieldException {
try {
return mClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
Class superClass = mClass.getSuperclass();
if (superClass == null) {
throw e;
} else {
return getField(superClass, fieldName);
}
}
}
}
Set private value use
RefUtil.setFieldValue(<your_class_object>, "your_variableName", newValue);
Get private value use
Object value = RefUtil.getPrivateFieldValue(<your_class_object>, "your_variableName");
This one can access private fields as well without having to do anything
import org.apache.commons.lang3.reflect.FieldUtils;
Object value = FieldUtils.readField(entity, fieldName, true);
As per the Javadoc of Class.getField (emphasis mine):
Returns a Field object that reflects the specified public member field of the class or interface represented by this Class object.
This method only returns public fields. Since a_field is private, it won't be found.
Here's a working code:
public class Main {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("Child");
Object cc = clazz.newInstance();
Field f1 = cc.getClass().getField("a_field");
f1.set(cc, "reflecting on life");
String str1 = (String) f1.get(cc);
System.out.println("field: " + str1);
}
}
class Father implements Serializable {
public String a_field;
}
class Child extends Father {
//empty class
}
Note that I also changed your line String str1 = (String) f1.get(cc.getClass()); to String str1 = (String) f1.get(cc); because you need to give the object of the field, not the class.
If you want to keep your field private, then you need to retrieve the getter / setter method and invoke those instead. The code you have given does not work because, to get a method, you also need to specify it's arguments, so
cc.getClass().getMethod("setA_field");
must be
cc.getClass().getMethod("setA_field", String.class);
Here's a working code:
public class Main {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("Child");
Object cc = clazz.newInstance();
cc.getClass().getMethod("setA_field", String.class).invoke(cc, "aaaaaaaaaaaaaa");
String str1 = (String) cc.getClass().getMethod("getA_field").invoke(cc);
System.out.println("field: " + str1);
}
}
class Father implements Serializable {
private String a_field;
public String getA_field() {
return a_field;
}
public void setA_field(String a_field) {
this.a_field = a_field;
}
}
class Child extends Father {
//empty class
}

How to "merge" two objects of the same class

The code is groovy but the answer can be both, Groovy or Java.
I have a Person class with this fields:
class Person(){
String name
String lasName
}
I have a method that returns two objects from the same class. One object with some fields and the other with the rest, in my example it would be like this:
person1 = "name : Jon"
person2 = "lastName : Snow"
What I need is to replace all the null fields of person1 with the person2 field if this is not null, in our example, the output would be:
person1.merge(person2)
person1= "name : Jon, lastName : Snow"
Is there any method on Java or Groovy to do something similar to this without writing all my fields(using some kind of loop)?
If there isn't any default method to use, how can I iterate through all the fields from a class?
Just tested using reflection. The desired output is
merged person:Person{name=John, lastName=Snow}
public static void testReflection() {
Person p1 = new Person("John", null);
Person p2 = new Person(null, "Snow");
Person merged = (Person) mergePersons(p1, p2);
System.out.println("merged person:" + merged);
}
public static Object mergePersons(Object obj1, Object obj2) throws Exception {
Field[] allFields = obj1.getClass().getDeclaredFields();
for (Field field : allFields) {
if (Modifier.isPublic(field.getModifiers()) && field.isAccessible() && field.get(obj1) == null && field.get(obj2) != null) {
field.set(obj1, field.get(obj2));
}
}
return obj1;
}
mergePersons accepts two Objects.
Then it go through all fields and validate if the first object has a null value.
If yes, then it verify if the second object is not nulled.
If this is true it assigns the value to the first Object.
Providing this solution you only access public data. If you want to access private data aswell, you need to remove the Modifier verification and set if accessible before like:
public static Object mergePersons(Object obj1, Object obj2) throws Exception {
Field[] allFields = obj1.getClass().getDeclaredFields();
for (Field field : allFields) {
if (!field.isAccessible() && Modifier.isPrivate(field.getModifiers()))
field.setAccessible(true);
if (field.get(obj1) == null && field.get(obj2) != null) {
field.set(obj1, field.get(obj2));
}
}
return obj1;
}
This is a quick (and presumptuous) approach that is basically the same as using reflection on the fields but instead uses:
Groovy's built-in getProperties() method on java.lang.Object, which provides us with a Map of its property names and values
Groovy's default Map constructor, which allows use to create instances of an Object given a Map of properties.
Given these two features, you can describe each object you want to merge as a Map of their properties, strip out the null-valued entries, combine the Maps together (and remove the pesky 'class' entry which is readonly), and use the merged Map to construct your merged instance.
class Person {
String first, last, middle
}
def p1 = new Person(first: 'bob')
def p2 = new Person(last: 'barker')
Person merged = (p1.properties.findAll { k, v -> v } // p1's non-null properties
+ p2.properties.findAll { k, v -> v }) // plus p2's non-null properties
.findAll { k, v -> k != 'class' } // excluding the 'class' property
assert merged.first == 'bob'
assert merged.last == 'barker'
assert merged.middle == null
Given Groovy fields are implemented as a getter/setter pair with a backing field you can probably do it this way in Groovy:
static <T> void merge(T from, T to) {
from.metaClass.properties.findAll { p ->
p.getProperty(to) == null &&
p.getProperty(from) != null &&
to.respondsTo(MetaProperty.getSetterName(p.name))
}
.each {
p -> p.setProperty(to, p.getProperty(from))
}
}
You're going to have to go the reflection route. I'm assuming you have a default constructor, otherwise the following won't work. Also, it needs two same types.
public static <T> T mergeObjects(T first, T second) throws IllegalAccessException, InstantiationException {
Class<?> clazz = first.getClass();
Field[] fields = clazz.getDeclaredFields();
Object returnValue = clazz.newInstance();
for (Field field : fields) {
field.setAccessible(true);
Object value1 = field.get(first);
Object value2 = field.get(second);
Object value = (value1 != null) ? value1 : value2;
field.set(returnValue, value);
}
return (T) returnValue;
}
Here is example
import java.lang.reflect.Field;
public class Merge2Obj {
private String name;
private String lasName;
public Merge2Obj() {
super();
}
public Merge2Obj(String name, String lasName) {
super();
this.name = name;
this.lasName = lasName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLasName() {
return lasName;
}
public void setLasName(String lasName) {
this.lasName = lasName;
}
public static <T> T mergeObjects(T first, T second) throws IllegalAccessException, InstantiationException {
Class<?> clazz = first.getClass();
Field[] fields = clazz.getDeclaredFields();
Object returnValue = clazz.newInstance();
for (Field field : fields) {
field.setAccessible(true);
Object value1 = field.get(first);
Object value2 = field.get(second);
Object value = (value1 != null) ? value1 : value2;
field.set(returnValue, value);
}
return (T) returnValue;
}
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Merge2Obj obj1 = new Merge2Obj("ABC", null);
Merge2Obj obj2 = new Merge2Obj("PQR", "LMN");
Merge2Obj obj3 = mergeObjects(obj1, obj2);
System.out.println(obj3.name);
System.out.println(obj3.lasName);
}
}
Assuming a mutable data class with getters and setters, Apache BeanUtils may suit your needs.
By default BeanUtilBeansBean.copyProperties(Object dest, Object orig) looks for pairs of T orig.get*() and dest.set*(T value), and calls the latter with the result of the former.
But you can inject a custom PropertyUtilsBean, so you could wrap the default one to prevent it from replacing non-null properties:
public NoClobberPropertyUtilsBean extends PropertyUtilsBean {
#Override
public void setSimpleProperty((Object bean,
String name,
Object value)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException {
if(getProperty(bean,name) == null) {
super.setSimpleProperty(bean,name,value);
}
}
}
Now you can merge with:
BeanUtilsBean beanUtils = new BeanUtilsBean(new ConvertUtilsBean(), new NoClobberPropertyUtilsBean());
Person merged = new Person();
beanUtils.copyProperties(person1);
beanUtils.copyProperties(person2);
If a property is non-null in both sources, the first copyProperties wins.
You could of course change the semantics, for example it would behave a different way if the guard was if(value != null).
At one level BeanUtils is just a wrapper around the kind of Reflection operations other answers suggest. It's up to you whether you want the extra level of abstraction. You may need to override more methods if you want to support map/list members, or BeanUtils' DynaBean class.

Set private field value with reflection

I have 2 classes: Father and Child
public class Father implements Serializable, JSONInterface {
private String a_field;
//setter and getter here
}
public class Child extends Father {
//empty class
}
With reflection I want to set a_field in Child class:
Class<?> clazz = Class.forName("Child");
Object cc = clazz.newInstance();
Field f1 = cc.getClass().getField("a_field");
f1.set(cc, "reflecting on life");
String str1 = (String) f1.get(cc.getClass());
System.out.println("field: " + str1);
but I have an exception:
Exception in thread "main" java.lang.NoSuchFieldException: a_field
But if I try:
Child child = new Child();
child.setA_field("123");
it works.
Using setter method I have same problem:
method = cc.getClass().getMethod("setA_field");
method.invoke(cc, new Object[] { "aaaaaaaaaaaaaa" });
To access a private field you need to set Field::setAccessible to true. You can pull the field off the super class. This code works:
Class<?> clazz = Child.class;
Object cc = clazz.newInstance();
Field f1 = cc.getClass().getSuperclass().getDeclaredField("a_field");
f1.setAccessible(true);
f1.set(cc, "reflecting on life");
String str1 = (String) f1.get(cc);
System.out.println("field: " + str1);
Using FieldUtils from the Apache Commons Lang 3:
FieldUtils.writeField(childInstance, "a_field", "Hello", true);
The true forces it to set, even if the field is private.
Kotlin verison
Get private variable using below extension functions
fun <T : Any> T.getPrivateProperty(variableName: String): Any? {
return javaClass.getDeclaredField(variableName).let { field ->
field.isAccessible = true
return#let field.get(this)
}
}
Set private variable value get the variable
fun <T : Any> T.setAndReturnPrivateProperty(variableName: String, data: Any): Any? {
return javaClass.getDeclaredField(variableName).let { field ->
field.isAccessible = true
field.set(this, data)
return#let field.get(this)
}
}
Get variable use:
val bool = <your_class_object>.getPrivateProperty("your_variable") as String
Set and get variable use:
val bool = <your_class_object>.setAndReturnPrivateProperty("your_variable", true) as Boolean
val str = <your_class_object>.setAndReturnPrivateProperty("your_variable", "Hello") as String
Java version
public class RefUtil {
public static Field setFieldValue(Object object, String fieldName, Object valueTobeSet) throws NoSuchFieldException, IllegalAccessException {
Field field = getField(object.getClass(), fieldName);
field.setAccessible(true);
field.set(object, valueTobeSet);
return field;
}
public static Object getPrivateFieldValue(Object object, String fieldName) throws NoSuchFieldException, IllegalAccessException {
Field field = getField(object.getClass(), fieldName);
field.setAccessible(true);
return field.get(object);
}
private static Field getField(Class mClass, String fieldName) throws NoSuchFieldException {
try {
return mClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
Class superClass = mClass.getSuperclass();
if (superClass == null) {
throw e;
} else {
return getField(superClass, fieldName);
}
}
}
}
Set private value use
RefUtil.setFieldValue(<your_class_object>, "your_variableName", newValue);
Get private value use
Object value = RefUtil.getPrivateFieldValue(<your_class_object>, "your_variableName");
This one can access private fields as well without having to do anything
import org.apache.commons.lang3.reflect.FieldUtils;
Object value = FieldUtils.readField(entity, fieldName, true);
As per the Javadoc of Class.getField (emphasis mine):
Returns a Field object that reflects the specified public member field of the class or interface represented by this Class object.
This method only returns public fields. Since a_field is private, it won't be found.
Here's a working code:
public class Main {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("Child");
Object cc = clazz.newInstance();
Field f1 = cc.getClass().getField("a_field");
f1.set(cc, "reflecting on life");
String str1 = (String) f1.get(cc);
System.out.println("field: " + str1);
}
}
class Father implements Serializable {
public String a_field;
}
class Child extends Father {
//empty class
}
Note that I also changed your line String str1 = (String) f1.get(cc.getClass()); to String str1 = (String) f1.get(cc); because you need to give the object of the field, not the class.
If you want to keep your field private, then you need to retrieve the getter / setter method and invoke those instead. The code you have given does not work because, to get a method, you also need to specify it's arguments, so
cc.getClass().getMethod("setA_field");
must be
cc.getClass().getMethod("setA_field", String.class);
Here's a working code:
public class Main {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("Child");
Object cc = clazz.newInstance();
cc.getClass().getMethod("setA_field", String.class).invoke(cc, "aaaaaaaaaaaaaa");
String str1 = (String) cc.getClass().getMethod("getA_field").invoke(cc);
System.out.println("field: " + str1);
}
}
class Father implements Serializable {
private String a_field;
public String getA_field() {
return a_field;
}
public void setA_field(String a_field) {
this.a_field = a_field;
}
}
class Child extends Father {
//empty class
}

Determine if a field is a type I created, using reflection

Assuming I have an object and I took it fields:
Field[] fields = obj.getFields();
Now I'm iterating through each one and would like to print their members if it's some kind of class, otherwise just use field.get(obj) in case it's a string, int or anything that this command will print its value, not just the reference pointer.
How can I detect it?
You can get, without instantiation required, the Type of each field of a class like this:
public class GetFieldType {
public static void main (String [] args) {
Field [] fields = Hello.class.getFields();
for (Field field: fields) {
System.out.println(field.getGenericType());
}
}
public static class Hello {
public ByeBye bye;
public String message;
public Integer b;
...
}
}
You can use instanceof to tell the objects apart.
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
Object[] objects = new Object[4];
objects[0] = new Integer(2);
objects[1] = "StringTest";
objects[2] = new BigDecimal(2.00d);
for (Object obj : objects) {
if (obj != null) {
if (obj instanceof BigDecimal) {
System.out.println("bigdecimal found " + obj);
} else if (obj instanceof String) {
System.out.println("String found " + obj);
} else {
System.out.println("Integer found " + obj);
}
}
else{
System.out.println("object is null");
}
}
}
If you need to test if an object is from your project, you can look at the package name and compare it to your project's package name.
You can either do this on the declared type of the field or on the runtime type of the field contents. The snippet below demonstrates the latter approach:
SomeClass foo = new SomeClass();
for (Field f : foo.getClass().getDeclaredFields()) {
boolean wasAccessible = f.isAccessible();
try {
f.setAccessible(true);
Object object = f.get(foo);
if (object != null) {
if (object.getClass().getPackage().getName()
.startsWith("your.project.package")) {
// one of yours
}
} else {
// handle a null value
}
} finally {
f.setAccessible(wasAccessible);
}
}
Do remember that obj.getFields(); only returns publicly-accessible fields. You may want to consider getDeclaredFields() as I've done above. If you stick with getFields(), you can omit the accessibility code in the above example.
With a bit of work, you could distinguish your classes by the classloader that loaded them. Take a look at this:
Find where java class is loaded from
Though this could help, it's not going to be the silver bullet for your problem, mainly because:
primitives (byte, short, char, int, long, float, double, and boolean) are not classes.
the architecture of classloaders is different in different app servers.
the same class could be loaded many times by different classloaders.
what I understood is you what to go recursive in object hierarchy and get values of primitives
public class ParentMostClass {
int a = 5;
OtherClass other = new OtherClass();
public static void main(String[] args) throws IllegalArgumentException,
IllegalAccessException {
ParentMostClass ref = new ParentMostClass();
printFiledValues(ref);
}
public static void printFiledValues(Object obj)
throws IllegalArgumentException, IllegalAccessException {
Class<? extends Object> calzz = obj.getClass();
Field[] fileds = obj.getClass().getDeclaredFields();
for (Field field : fileds) {
Object member = field.get(obj);
// you need to handle all primitive, they are few
if (member instanceof String || member instanceof Number) {
System.out.println(calzz + "->" + field.getName() + " : "
+ member);
} else {
printFiledValues(member);
}
}
}
}
public class OtherClass {
int b=10;
}
I got output as
class com.example.ParentMostClass->a : 5
class com.example.OtherClass->b : 10

Access Class Variable on general Object of that class

I have a lots of classes for example this one:
public class DepartmentST {
public Long id = null;
public String name = null;
public String comments = null;
public Long[] profiles = null;
public Boolean default_val = false;
}
In main class I create objects of those classes and sent it to general method for example:
DepartmentST mydepartment = new DepartmentST();
generalMethod(mydepartment);
In general Method I want to access to object fields (this my question how?)
public generalMethod(Object myObj) {
Field[] fields = myObj.getClass().getFields();
for(Field field : fields) {
String fieldName = field.getName();
// I want to access that field how can i tell myObj.fielName ?
}
}
I'm new in Java I don't know it's stupid question or not.
thanks for any help in advance.
see http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Field.html#get(java.lang.Object)
public generalMethod(Object myObj) {
Field[] fields = myObj.getClass().getFields();
for(Field field : fields) {
String fieldName = field.getName();
// I want to access that field how can i tell myObj.fielName ?
Class c = field.getType();
if (c instanceOf Integer) {
Integer value = field.getInt (myObj);
}
// or
Object value = field.get (myObj);
}
}
You need to "cast" the object to a DepartmentST object:
if (myObj instanceof DepartmentST) {
DepartmentST department = (DepartmentST) myObj;
// continue with code
Then use that object instead of myObj.
Basically this code breaks the encapsulation. You need private fields, and you access them through getters and setters. Reflection is another way to go (depending on the context).

Categories