Is there any way to read and print the object attribute dynamically(Java) ? for example if I have following object
public class A{
int age ;
String name;
float income;
}
public class B{
int age;
String name;
}
public class mainA{
A obj1 = new A();
method(A);
method(B);
}
the output should be like
While running method(A):
Attribute of Object are age,name,income;
While executing method(B):
Attribute of Objects are age,name;
My question is I can pass various object in method(), is there any way I can access the attribute of the differnt object in general.
You want to use The Reflection API. Specifically, take a look at discovering class members.
You could do something like the following:
public void showFields(Object o) {
Class<?> clazz = o.getClass();
for(Field field : clazz.getDeclaredFields()) {
//you can also use .toGenericString() instead of .getName(). This will
//give you the type information as well.
System.out.println(field.getName());
}
}
I just wanted to add a cautionary note that you normally don't need to do anything like this and for most things you probably shouldn't. Reflection can make the code hard to maintain and read. Of course there are specific cases when you would want to use Reflection, but those relatively rare.
Using org.apache.commons.beanutils.PropertyUtils we can do this. If the proper getters and setters are defined for the bean we can also dynamically set the value:
import org.apache.commons.beanutils.PropertyUtils;
import java.beans.PropertyDescriptor;
public class PropertyDescriptorTest {
public static void main(String[] args) {
// Declaring and setting values on the object
AnyObject anObject = new AnyObject();
anObject.setIntProperty(1);
anObject.setLongProperty(234L);
anObject.setStrProperty("string value");
// Getting the PropertyDescriptors for the object
PropertyDescriptor[] objDescriptors = PropertyUtils.getPropertyDescriptors(anObject);
// Iterating through each of the PropertyDescriptors
for (PropertyDescriptor objDescriptor : objDescriptors) {
try {
String propertyName = objDescriptor.getName();
Object propType = PropertyUtils.getPropertyType(anObject, propertyName);
Object propValue = PropertyUtils.getProperty(anObject, propertyName);
// Printing the details
System.out.println("Property="+propertyName+", Type="+propType+", Value="+propValue);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
To set the value of a particular property:
// Here we have to make sure the value is
// of the same type as propertyName
PropertyUtils.setProperty(anObject, propertyName, value);
Output will be:
Property=class, Type=class java.lang.Class, Value=class genericTester.AnyObject
Property=intProperty, Type=int, Value=1
Property=longProperty, Type=class java.lang.Long, Value=234
Property=strProperty, Type=class java.lang.String, Value=string value
You can use reflection to get every field from your object (if security configuration allows you).
If you need it not for the sake of self-education, then it may be worth using ReflectionUtils from Apache Commons.
You can use reflection, but the API is not very nice to use. But what you are trying to do is not at all object-oriented. The A and B should have method "print yourself" which would output their values (you should specify the method in superclass/interface to call the method using polymorphism).
I think I would consider a different approach.
If you really want to treat these like data is there any reason they couldn't be hashtables (Do they have associated code)?
Reflection will do it but it's a last resort--you should always seriously consider different approaches before dropping to reflection.
Cases where you must access variables like that exist--like database mapping (Hibernate) and injection (Spring). You might want to consider if a packaged solution like that fits your need so that future programmers can understand what you did without learning everything about your specific solution.
Also, Spring injection can do things that might fit your needs.
Also also if you are going to use reflection, seriously consider annotations so that you aren't tying your functionality to what should be simple arbitrary attribute names.
Related
Currently I have an endpoint which returns a a fairly large data object.
This call for all objects of that type can generate 20MBs of data. However not always the clients need all the information in the object, quite often a subset of data is all that is required. I want to give the client the option to pass in some parameters to determine what parts of the object they require.
For example, specifying an array of restriction fields with each field itself a group of instance members on the object, a user can restict how much f the object they want. Looking at the figure Object below, restriction field value r1 may refer to instance members a and b.
example request "myurl/restrict=r1,r2"
MyObject(){
a;
b;
c;
d;
e;
f;
g;
h;
.... many more fields
}
So with that in mind, I created an ENUM to model the restriction fields and the subset of instance members which each instance field represents.
Now on the DB query I want to use the ENUM(s) values to decide which parts of the object I want.
So the select query will select the Object and the object can be partially instantiated by calling whatever get/set methods are required. I have implemented this on the query side by using the request params(i.e. groupings of instance members) and performing reflection on the object returned from the DB to get/set the instance fields on the object to return.
I am however, unsure if there is an already existing design pattern for this problem other than a refactor or create a new endpoints for the "lighter" objects. I dont want to argue that case, I just want to discuss for the problem at hand, is reflection a valid method of fulfilling the requirement and if not why not and what are the alternatives.
I believe this solution can cater for change easily, Only the enum needs updated if instance members change or a restriction grouping needs adapting. The rest layer or data layer requires no change. However I am unsure of the performance impact, i only implemented this today so I haven't been able to benchmark yet.
I guess the real question is; is there a design pattern for partial object creation of unknown member fields at runtime
Below is psuedo of how i implemented the select aspect below.
select(MyObj obj){
//get all the restricted fields from the request
// Instantiate new object
// for each restriction field(i.e. instance member)
// use reflection to invoke the set method of the new object(partial) passing the get method of the method argument(full object)
}
You can use object mapper for that
Employee -> name , id, uid, address
Using objectmapper readvaluetotree
Returns JsonNode/ObjectNode
Select your keys to construct the new json
Json= { "name": "xyz", "id": 101, "uid": "xoz", "address": "xqp street" }
Delete the keys which you don't need using
jsonNode.remove or delete key
then use the jsonNode to parse back to object
Employee em = objectmapper.readValue( json, Employee.class)
I think I may have found a really nice method for this task leveraging the functional aspect of Java8. Indeed this could also be implemented using an anonymous class pre Java8.
I can make use of this in the Enum and construct each one with a BiConsumer.
I can then implement that copy method while I iterate through the passed in arguments.
Now I have have the behaviour I had with reflection but without the performance impact.
public enum RestrictFields {
R1((source, target) -> {
target.setA(source.getA());
target.setB(source.getB());
target.setC(source.getC());
}),
R2((source, target) -> {
target.setD(source.D());
});
private final BiConsumer<MyObj, MyObj> copier;
private RestrictFields (final BiConsumer<MyObj, MyObj> copier) {
this.copier = copier;
}
public void copy(final MyObj source, final MyObj target){
this.copier.accept(source, target);
}
}
Now when in the select clause I can cycle through the passed Enum Values and invoke the copy method and build the restricted object based on that.
public Object select(MyObj source) {
MyObj myobj = new MyObj ();
if (!restrictedFields.isEmpty()) {
// Instead of refelction here I can use the biconsumer in the enum
for (RestrictFields field : restrictedFields) {
field.copy(source, myobj);
}
return myObj;
}
return source;
}
C# 6.0 introduced the nameof() operator, that returns a string representing the name of any class / function / method / local-variable / property identifier put inside it.
If I have a class like this:
class MyClass
{
public SomeOtherClass MyProperty { get; set; }
public void MyMethod()
{
var aLocalVariable = 12;
}
}
I can use the operator like this:
// with class name:
var s = nameof(MyClass); // s == "MyClass"
// with properties:
var s = nameof(MyClass.OneProperty); // s == "OneProperty"
// with methods:
var s = nameof(MyClass.MyMethod); // s == "MyMethod"
// with local variables:
var s = nameof(aLocalVariable); // s == "aLocalVariable".
This is useful since the correct string is checked at compile time. If I misspell the name of some property/method/variable, the compiler returns an error. Also, if I refactor, all the strings are automatically updated. See for example this documentation for real use cases.
Is there any equivalent of that operator in Java? Otherwise, how can I achieve the same result (or similar)?
It can be done using runtime byte code instrumentation, for instance using Byte Buddy library.
See this library: https://github.com/strangeway-org/nameof
The approach is described here: http://in.relation.to/2016/04/14/emulating-property-literals-with-java-8-method-references/
Usage example:
public class NameOfTest {
#Test
public void direct() {
assertEquals("name", $$(Person.class, Person::getName));
}
#Test
public void properties() {
assertEquals("summary", Person.$(Person::getSummary));
}
}
Sadly, there is nothing like this. I had been looking for this functionality a while back and the answer seemed to be that generally speaking, this stuff does not exist.
See Get name of a field
You could, of course, annotate your field with a "Named" annotation to essentially accomplish this goal for your own classes. There's a large variety of frameworks that depend upon similar concepts, actually. Even so, this isn't automatic.
You can't.
You can get a Method or Field using reflection, but you'd have to hardcode the method name as a String, which eliminates the whole purpose.
The concept of properties is not built into java like it is in C#. Getters and setters are just regular methods. You cannot even reference a method as easily as you do in your question. You could try around with reflection to get a handle to a getter method and then cut off the get to get the name of the "property" it resembles, but that's ugly and not the same.
As for local variables, it's not possible at all.
You can't.
If you compile with debug symbols then the .class file will contain a table of variable names (which is how debuggers map variables back to your source code), but there's no guarantee this will be there and it's not exposed in the runtime.
I was also annoyed that there is nothing comparable in Java, so I implemented it myself: https://github.com/mobiuscode-de/nameof
You can simply use it like this:
Name.of(MyClass.class, MyClass::getProperty)
which would just return the String
"property"
It's also on , so you can add it to your project like this:
<dependency>
<groupId>de.mobiuscode.nameof</groupId>
<artifactId>nameof</artifactId>
<version>1.0</version>
</dependency>
or for Gradle:
implementation 'de.mobiuscode.nameof:nameof:1.0'
I realize that it is quite similar to the library from strangeway, but I thought it might be better not to introduce the strange $/$$ notation and enhanced byte code engineering. My library just uses a proxy class on which the getter is called on to determine the name of the passed method. This allows to simply extract the property name.
I also created a blog post about the library with more details.
Lombok has an experimental feature #FieldNameConstants
After adding annotation you get inner type Fields with field names.
#FieldNameConstants
class MyClass {
String myProperty;
}
...
String s = MyClass.Fields.myProperty; // s == "myProperty"
Is there anyway to find a property descriptor recursively using Java reflection?
Imagine a scenario where a User class has a field called profile, which itself is another class which has the email attribute.
By having the user object, I need to have access to profile.email so the desirable method signature should be something similar to this:
public PropertyDescriptor findPropertyDescriptor(Class<?> clazz, String path)
{
// Code!
}
And the call would be something like:
findPropertyDescriptor(User.class, "profile.email")
I'm also thinking that calls like below should be possible as well:
findPropertyDescriptor(User.class, "addresses[2].postCode")
Since nobody has come up with a solution, I have to answer my question here.
Thanks to Spring, this has been already implemented:
public static <T> PropertyDescriptor getPropertyDescriptor(T rootObject, String path)
{
BeanWrapperImpl wrapper = new BeanWrapperImpl(rootObject);
return wrapper.getPropertyDescriptor(path);
}
In addition to the requirement, mentioned in the question, it also supports Maps.
I have this question. But it will be difficult for me to explain as I don't know exact terms to use. Hope someone will understand. I'll try to discribe to the best i can. I feel like this is much related to parsing
Say there are two classes. And in both classes I have some variables, say strings (just for simplicity, variable type can be any), which have similar names.
Eg:
class ClassA{
String x,y,z;
}
class ClassB{
String x,y,z;
}
Now, what i need is, i need to copy the value of one class's variable values to other classes corresponding variable.
Eg:
ClassA aa=new ClassA();
ClassB bb=new ClassB();
//set bb's variables
aa.x=bb.x;
aa.y=bb.y;
aa.z=bb.z;
like that.
But please note that what i need is not the above method. I hope there will be a way to write a simple method, so that it will identify the relevent variable by the name passed to it. Then it will do the value assignment accordingly.
My imagined method is like this,
void assign(String val){
// aa.<val>=val
}
For example if you pass bb.x to assign(...) method, then it will do aa.x=bb.x assignment.
Hope this is clear enough. There must be a better way to explain this. If someone know it please edit the post(+title) to make it more clear (But save my idea)..
Please let me know if there's a way to achieve this.
Thanks!
Dozer is fine, see Jean-Remy's answer.
Also, if the variables have getters and setters according to the JavaBeans standard, there are a number of technologies that could help you, e.g. Apache Commons / BeanUtils
Sample code (not tested):
final Map<String, Object> aProps = BeanUtils.describe(a);
final Map<String, Object> bProps = BeanUtils.describe(b);
aProps.keySet().retainAll(bProps.keySet());
for (Entry<String, Object> entry : aProps.entrySet()) {
BeanUtils.setProperty(b,entry.getKey(), entry.getValue());
}
Update:
If you don't have getters and setters, here's a quick hack that copies field values from one class to another as long as the fields have common names and types. I haven't tested it, but it should be OK as a starting point:
public final class Copier {
public static void copy(final Object from, final Object to) {
Map<String, Field> fromFields = analyze(from);
Map<String, Field> toFields = analyze(to);
fromFields.keySet().retainAll(toFields.keySet());
for (Entry<String, Field> fromFieldEntry : fromFields.entrySet()) {
final String name = fromFieldEntry.getKey();
final Field sourceField = fromFieldEntry.getValue();
final Field targetField = toFields.get(name);
if (targetField.getType().isAssignableFrom(sourceField.getType())) {
sourceField.setAccessible(true);
if (Modifier.isFinal(targetField.getModifiers())) continue;
targetField.setAccessible(true);
try {
targetField.set(to, sourceField.get(from));
} catch (IllegalAccessException e) {
throw new IllegalStateException("Can't access field!");
}
}
}
}
private static Map<String, Field> analyze(Object object) {
if (object == null) throw new NullPointerException();
Map<String, Field> map = new TreeMap<String, Field>();
Class<?> current = object.getClass();
while (current != Object.class) {
for (Field field : current.getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers())) {
if (!map.containsKey(field.getName())) {
map.put(field.getName(), field);
}
}
}
current = current.getSuperclass();
}
return map;
}
}
Call Syntax:
Copier.copy(sourceObject, targetObject);
Did you ever heared about Dozer ? : http://dozer.sourceforge.net/
Dozer
Dozer is a Java Bean to Java Bean mapper that recursively copies data from one object to another. Typically, these Java Beans will be of different complex types.
Dozer supports simple property mapping, complex type mapping, bi-directional mapping, implicit-explicit mapping, as well as recursive mapping. This includes mapping collection attributes that also need mapping at the element level.
Dozer allow you to map Java Beans :
using their names (implicit mapping), i.e mapping ClassA.x to ClassB.x
providing hability to map diffrent structures (explicit mapping) with different names with (quite simple) xml or annoation configuration .
Here a XML example on the library site :
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozer.sourceforge.net
http://dozer.sourceforge.net/schema/beanmapping.xsd">
<mapping>
<class-a>org.dozer.vo.TestObject</class-a>
<class-b>org.dozer.vo.TestObjectPrime</class-b>
<field>
<a>one</a>
<b>onePrime</b>
</field>
</mapping>
<!-- SNIP ... -->
</mappings>
This will map object org.dozer.vo.TestObject into TestObjectPrime, mapping all variable that are identicals together (like in your case) and variables TestObjectFoo.oneFoo into TestObjectFooPrime.oneFooPrime.
Great, isn't it ?
Look here. Just use BeanUtils.copyProperties(newObject, oldObject);
new answer.
I'd suggest looking into Dover as it seems pretty straightforward.
The second option is serializing classes into XML and deserializing into your target class only on members that match.
The third option I mentioned in the comment was using reflection - http://java.sun.com/developer/technicalArticles/ALT/Reflection/
This technique allows for a nice design pattern called Introspection - Java introspection and reflection which in turn allows you to discover members of a certain class...
Now, having said that, one would simply "discover" members of ClassA, fill a ArrayList with their names, discover members of ClassB, fill another ArrayList with their names, and copy values of the intersecting set. At least that's my idea on it.
I have a bunch of third-party Java classes that use different property names for what are essentially the same property:
public class Foo {
public String getReferenceID();
public void setReferenceID(String id);
public String getFilename();
public void setFilename(String fileName);
}
public class Bar {
public String getRefID();
public void setRefID(String id);
public String getFileName();
public void setFileName(String fileName);
}
I'd like to be able to address these in a canonicalized form, so that I can treat them polymorphically, and so that I can do stuff with Apache BeanUtils like:
PropertyUtils.copyProperties(object1,object2);
Clearly it would be trivial to write an Adapter for each class ...
public class CanonicalizedBar implements CanonicalizedBazBean {
public String getReferenceID() {
return this.delegate.getRefID();
}
// etc.
}
But I wonder is there something out there more generalized and dynamic? Something that would take a one-to-many map of property name equivalences, and a delegate class, and produce the Adapter?
I've never used it, but I think you're looking for Dozer:
Dozer is a Java Bean to Java Bean mapper that recursively copies data
from one object to another. Typically, these Java Beans will be of
different complex types.
Dozer supports simple property mapping, complex type mapping,
bi-directional mapping, implicit-explicit mapping, as well as
recursive mapping. This includes mapping collection attributes that
also need mapping at the element level.
Dozer not only supports mapping between attribute names, but also
automatically converting between types. Most conversion scenarios are
supported out of the box, but Dozer also allows you to specify custom
conversions via XML.
First Option is Dozer.
Second option is Smooks Framework
with a tweak. It will be beneficial to use Smook's Graphical mapper.
Another option would be XStream with custom Mapper.
maybe something like that:
public class CanonicalizedBar implements CanonicalizedBazBean {
public String getReferenceID() {
Method m = this.delegate.getClass().getDeclaredMethod("getReferenceID");
if(m == null)
m = this.delegate.getClass().getDeclaredMethod("getRefID");
...
return m.invoke();
}
// etc.
}
Although, I personally have never used it. I noticed that a project called orika is noted as having the best performance and the ability to automatically understand many such mappings.
At any rate it also supports custom mappings and uses generated code to implicitly define the adapters.
You can also define a custom mapper, that is if you know how to canonize the member names you can use that knowledge to build a mapping that is true for all your objects. for instance:
DefaultFieldMapper myDefaultMapper = new DefaultFieldMapper() {
public String suggestMapping(String propertyName, Type<?> fromPropertyType) {
// split word according to camel case (apache commons lang)
String[] words= StringUtils.splitByCharacterTypeCamelCase(propertyName);
if(words[0].length() > 6) {
// trim first camel-cased word of propery name to 3 letters
words[0]= words[0].substring(0,2);
return StringUtils.join(words);
} else {
// remains unchanged
return propertyName;
}
}
}
mapperFactory.registerDefaultFieldMapper(myDefaultMapper );
I haven't done much with it but you may be able to use Aspect Oriented Programming to do this.
What you should be able to do I think is add a method to each of the classes that internally calls the real method. See this article about half way down it talks about mixins.
AspectJ is probably the most popular implementation.