Copy fields between similar classes in java - java

I have pairs of classes where the fields of one is a subset of the fields of another and the getters of the superset classes are all predictably named (getFoo()). Is there some way to efficiently copy all the common fields over from the superset class to the subset class, or at least auto-generate the code to do so.
I should note that:
For various reasons, I can't edit the superset classes, nor can I just use them throughout to avoid having to do the data copy.
I can potentially create new methods in the subset classes, but I can't change their fields.
We have dozens of these pairs, and some of the classes have many many fields so doing this by hand is unwieldy to say the least.
A colleague has come up with a method to create a generic copy method that uses java reflection to take any two classes, iterate through the fields as Strings, do string manipulation to determine the getter name, and then execute it to automatically set the field in the subset class. It's awful, but it appears to work. I'm really hoping there's a better way.
Edit: some simple code as requested
public class SuperClass {
private int foo;
private int bar;
private float bat;
public int getFoo() { return foo; }
public int getBar() { return bar; }
public float getBat() { return bat; }
}
public class SubClass {
private int foo;
private float bat;
}
//wanted
public static copySuperFieldsToSubMethod(Object super, Object sub) { ??? }
// also acceptable would be some way to autogenerate all the assignment
// functions needed

You could use the BeanUtils class in the Spring Framework to do this. It may not necessarily be any more efficient than your reflection-based technique, but it's certainly simple to code. I expect that all you would need to do is:
BeanUtils.copyProperties(source, target);
Javadoc for this method is available at http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/beans/BeanUtils.html#copyProperties(java.lang.Object,%20java.lang.Object)
If that doesn't suit, you could also consider using BeanWrapper / BeanWrapperImpl in the Spring Framework to iterate through the properties of your classes. That would be simpler than using low-level reflection APIs.

Similar to the first answer, but to clarify - spring is not needed. Commons BeanUtils.copy properties(Object dest, Object orig)
http://commons.apache.org/beanutils/api/org/apache/commons/beanutils/BeanUtils.html#copyProperties(java.lang.Object,%20java.lang.Object)

If you want to the task efficiently (in terms of runtime performance), then hand coding the copy using getters and setters is the way to go. Unless there is something funky about the getter or setter methods, their bodies will be inlined so that they are as fast as doing field assignments.
The reflective approach (e.g. using an existing class like BeanUtils) is less coding, but probably an order of magnitude slower than calling getters and setters in a simple way. If you try to implement this yourself, you may find yourself with more work than you bargained for, especially if your reflective copy class / method has to cope with overloaded methods, inheritance, value conversion, boxing/unboxing and so on.
With the code generation approach, you need to balance the effort and complexity of implementing the code generation (using whatever technology you choose) versus the effort of writing the copy methods by hand. You probably probably won't break even with the code generation approach before 20 classes ... and many more if you are not familiar with the technology.

To copy based on fields rather than getters and setters, you can use Spring's ReflectionUtils.shallowCopyFieldState().

I'd write a simple java tool to autogenerate the source code for classes that can populate the the subsets fields with the common fields from superset. This tool will use reflection to get the names of the getter and setter methods. The rest are (trivial) String operations to "write" a source file in memory and store it to a *.java file. Compile all this autogenerated files and add the class files to the classpath.
The class could look like this:
class AClassToBClassPopulator implements Populator {
#Overwrite
public void populate(Object superSet, Object subSet) {
subSet.setFieldA(superSet.getFieldA());
subSet.setFieldB(superSet.getFieldB());
// .. and so on. The method body is created through reflection
}
}

Can you provide some sample code from your app that depicts the scenario you have mentioned in your post?
Right now reflection seems like the best way , since it lets you inspect the class members at runtime.

This is obviously a task for Java's reflection and while others have already suggested valid although maybe a bit heavyweight solutions, here's one more:
About a year ago I wrote a smallish JavaBean property modifier library called BeanPropertyController. While I don't specifically recommend it to anyone, I do think that the namesake class of the library (see source) can be used as a reference to adopt similar functionality to your needs. As a quick example, here's how I used BPC to do (almost!) what you're asking:
// somewhere in code...
SuperClass a = new SuperClass();
a.foo = 101;
a.bar = 102;
a.bat = 103f;
SubClass b = new SubClass();
b.foo = 201;
b.bat = 202f;
BeanPropertyController fromB = BeanPropertyController.of(b, ExtractionDepth.QUESTIMATE);
BeanPropertyController toA = BeanPropertyController.of(a, ExtractionDepth.QUESTIMATE);
// This is where the magic happens:
for (String propertyName : fromB.getPropertyNames()) {
toA.mutate(propertyName, fromB.access(propertyName));
}
a = (SuperClass) toA.getObject();
b = (SubClass) fromB.getObject();
System.out.println("SuperClass' foo="+a.foo+" bar="+a.bar+" bat="+a.bat);
System.out.println("SubClass' foo="+b.foo+" bat="+b.bat);
This prints out
SuperClass' foo=201 bar=102 bat=202.0
SubClass' foo=201 bat=202.0
So, what I suggest is that you go to the URL I linked and adapt this piece of code to your needs. I'm quite sure you don't need the various instantiation methods, default value providers etc. which I've included. And yes, BPC can be considered to be deprecated.

Related

Is it ok to keep common code in a separate class and make the method static in java?

I would like to know if it safe and a good practice to keep common code in a separate class and make method static.
I have a class Car, that is constructed based on inputs from other classes. I need to apply some post construct processing after the Car object is created. Example below.
Class Travel uses Car and calls postConstructProcessing method.
CarProcessor is simillary used in other classes whenever car object is creates.
My question is should I make method process Static in CarProcessor.
Class car{
Type type;
Int model
Car(Type t, int m){
...
...
}
;
....
...}
Below class of code uses Car and calls postConstructProcessing method
public class Travel {
public void go(){
....
....
Car c = new Car(t,m);
new CarProcessor().process(c);
}
}
class CarProcessor{
public Car process(Car c){
If(c.type.value.equals("ABC"){
c.type.version=1.1;
}
if(c.model=5.7){
c.price=50k
}
}
}
My question is , is it safe and a good practice to make method process in CarProcessor static.
In general it's not great.
The most obvious problem is, if you are testing the go method, how do you replace/mock out CarProcessor::process?
The real problem is organizational though. When you are coding next time and looking for the functionality you'd expect to see in "Car" or "go", you type "car." or "go." into your IDE and hit ctrl-space, you'd expect to see all the interesting methods shown to you. How do you know to create a CarProcessor to proceed?
Some things are difficult to implement in OO though--in particular utilities. Look at the entire Math package in the java library. It's full of static methods that you just call. An oo fanatic would say these all belong in the Number class (maybe something like "Number.math.sqrt()?", but java didn't take that route--in fact they don't even have a good common number class (We have one, it's not good)--
But even when we have real classes like String, we lean towards "StringUtil" and such. This has led to a HUGE number of conflicting "Util" implementations of String. In this case part of the problem is that String is immutable and we can't really back-fill it with methods (probably a good thing). but in general, OO just isn't great for general-purpose utility methods.
Functions (which is what you are proposing) are not awesome, but are heavily used. If you have the ability to modify your business classes then that's almost always a better fit for this type of code.
Just to clarify: A Function is different from a Method--methods work on members (class variables), functions are stand-alone (Might as well be static).
Functions are a very old approach at organization. OO is a somewhat newer approach invented for when the sheer number of functions become too difficult to manage (conceptually).

finding package aka default-scoped members of java classes

I want to find all the default-scoped, aka package-scoped, class members in my project. (Other scopes are no problem, since I can search for the keyword public/protected/private, but there's no keyword to search for in this case.)
Is there an eclipse plugin or anything that can do this kind of search?
public class Foo {
private int a; // these are easy
protected int b; // to find,
public int c; // thanks to keywords
int d; // but ones like this?
}
You might want to look at javap:
http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/javap.html
It's primarily intended for disassembling classes, but it also lets you include/exclude class members of different scope (private vs public, for example)
Since javap does not appear to be a suitable solution and I don't know of any suitable plugin, you may have to write your own.
Feed it a list of classes.
for each class
Use Class.forName(className) to get the class object
use getDeclared{Classes,Fields,Methods,Constructors} to get the members.
for each member
Use java.lang.reflect.Modifiers.is{Public,Private,Protected}(member.getModifiers())
It is default if all three are false
If default report that member
You decide whether and how to recurse into inner classes.
I guess that solution will not work for classes nested inside methods. (Neither would javap, javadoc solve classes nested inside methods.) It will make things much simpler if you can just assert that you code does not have classes nested inside methods.

What is the point of getters and setters? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why use getters and setters?
I have read books on Java, saying that it is good to create setters and getters for variables such as x and y. For example:
public int getX(){
return x;
}
public void setX(int x){
this.x = x;
}
But what is the difference from that and
...(shape.x)... // Basically getX()
and
shape.x = 90; // Basically setX()
If setters and getters are better, what practical problems would arise?
Multiple reasons:
If you allow field access like
shape.x = 90
then you cannot add any logic in future to validate the data.
say if x cannot be less than 100 you cannot do it, however if you had setters like
public void setShapeValue(int shapeValue){
if(shapeValue < 100){
//do something here like throw exception.
}
}
You cannot add something like copy on write logic (see CopyOnWriteArrayList)
Another reason is for accessing fields outside your class you will have to mark them public, protected or default, and thus you loose control. When data is very much internal to the class breaking Encapsulation and in general OOPS methodology.
Though for constants like
public final String SOMETHING = "SOMETHING";
you will allow field access as they cannot be changed, for instance variable you will place them with getters, setters.
Another scenario is when you want your Class to be immutable, if you allow field access then you are breaking the immutability of your class since values can be changed. But if you carefully design your class with getters and no setters you keep the immutability intact.
Though in such cases you have to be careful in getter method to ensure you don't give out reference of objects(in case your class have object as instances).
We can use the private variables in any package using getters and setters.
Using getter and setter functions allow for constraints and encapsulation. Lets say x is the radius. shape.x = -10 would not make much sense. Also, if someone tries to set an illegal value, you can print an error, set a default value, or do nothing.
It is good practice to make member variables private so they cannot be modified directly by programs using them.
Mutator functions
Encapsulation
A lot of people have mentioned encapsulating the specifics of the implementation, which to me is the biggest reason to use getters and setters in a class. With this, you also get a lot of other benefits, including the ability to throw out and replace the implementation on a whim without needing to touch every piece of code that uses your class. In a small project, that's not a big benefit, but if your code ends up as a well-used (internal or public) library, it can be a huge benefit.
One specific example: complex numbers in mathematics. Some languages have them as a language or framework feature, others don't. I will use a mutable class as an example here, but it could just as easily be immutable.
A complex number can be written on the form a + bi with real and imaginary parts, lending itself well to [gs]etRealPart and [gs]etImaginaryPart.
However, in some cases it's easier to reason about complex numbers on polar form re^(iθ), giving [gs]etRadius (r) and [gs]etAngle (θ).
You can also expose methods like [gs]etComplexNumber(realPart, imaginaryPart) and [gs]etComplexNumber(radius, angle). Depending on the argument types these may or may not need different names, but then the class' consumer can use either as fits its needs.
The two forms are interchangeable; you can fairly easily convert from one to the other, so which form the class uses for internal storage is irrelevant to consumers of that class. However, consumers may use either form. If you choose the form a+bi for internal representation, and expose that using fields rather than getters and setters, not only do you force the class consumers to use that form, you also cannot later easily change your mind and replace the internal representation with re^(iθ) because that turns out to be easier to implement in your particular scenario. You're stuck with the public API you have defined, which mandates that specifically the real and imaginary parts are exposed using specific field names.
One of the best reasons I can think of for getters and setters is the permanence of a class's API. In languages like python you can access members by their name and switch them to methods later. Because functions behave differently than members in java once you access a property thats it. Restricting its scope later breaks the client.
By providing getters and setters a programmer has the flexibility to modify members and behavior freely as long as the adhere to the contract described by the public API.
Another good reason to user getter and setter can be understand by the following example
public class TestGetterSetter{
private String name ;
public void setName(String name){
this.name = name ;
}
public String getName(){
return this.name ;
}
}
The point of getters and setters is that only they are meant to be used to access the private variable, which they are getting or setting. This way you provide encapsulation and it will be much easier to refactor or modify your code later.
Imagine you use name instead of its getter. Then if you want to add something like a default (say the default name is 'Guest' if it wasn't set before), then you'll have to modify both the getter and the sayName function.
public class TestGetterSetter{
private String name ;
public void setName(String name){
this.name = name ;
}
public String getName(){
if (this.name == null ){
setName("Guest");
}
return this.name ;
}
}
There is no requirement for getters and setter to start with get and set - they are just normal member functions. However it's a convention to do that. (especially if you use Java Beans)
Let's say, hypothetically, you find a library that does a better job of what you have been doing in your own class (YourClass). The natural thing to do at this point is to make YourClass a wrapper interface to that library. It still has a concept of "X" which your client code needs to get or set. Naturally, at this point you pretty much have to write the accessor functions.
If you neglected to use accessor functions and let your client code access YourClass.x directly, you would now have to rewrite all of your client code that ever touched YourClass.x. But if you were using YourClass.getX() and YourClass.setX() from the beginning, you will only need to rewrite YourClass.
One of the key concepts of programming, and especially object oriented programming, is hiding implementation details so that they're not used directly by code in other classes or modules. This way, if you ever change the implementation details (as in the example above), the client code doesn't know the difference and doesn't have to be modified. For all your client code knows, "x" might be a variable, or it might be a value that is calculated on the fly.
This is an oversimplification and doesn't cover all the scenarios where hiding implementation is beneficial, but it is the most obvious example. The concept of hiding implementation details is pretty strongly tied to OOP now, but you can find discussions of it going back decades before OOP was dreamed up. It goes back to one of the core concepts of software development, which is to take a big nebulous problem, and divide it into small well-defined problems which can be solved easily. Accessor functions help keep your small sub-tasks separate and well-defined: The less your classes know about each other's internals, the better.
There are lots of reasons. Here are just a few.
Accessors, getters in particular, often appear in interfaces. You can't stipulate a member variable in an interface.
Once you expose this member variable, you can't change your mind about how it's implemented. For example, if you see a need later to switch to a pattern like aggregation, where you want the "x" property to actually come from some nested object, you end up having to copy that value and try to keep it in sync. Not good.
Most of the time you are much better off not exposing the setter. You can't do that with public fields like x.
Before get into the answer, we gotta know something prior...! "JavaBeans".
JavaBeans are java classes that have properties. For our purpose, think of properties as private instance variables. since they're private, the only way they can be accessed
from outside of their class is through 'methods'in the class.
The methods that change a propertiy's value are called setter methods, and the methods that retrieve a property's value are called getter methods.
I would say that neither the getters/setters nor the public members are good Object Oriented design. They both break OOP Encapsulation by exposing an objects data to the world that probably shouldn't be accessing the properties of the object in the first place.
This is done by applying the encapsulation principle of OOP.
A language mechanism for restricting access to some of the object's components.
This means, you must define the visibility for the attributes and methods of your classes. There are 3 common visibilities:
Private: Only the class can see and use the attributes/methods.
Protected: Only the class and its children can see and use the attributes/methods.
Public: Every class can see and use the attributes/methods.
When you declare private/protected attributes, you are encouraged to create methods to obtain the value (get) and change the value (set). One example about visibility is the [ArrayList][2] class: it has a size property to know the actual size of the inner array. Only the class must change its value, so the code is something like
public class ArrayList<E> {
private int size;
private Object[] array;
public getSize() {
return this.size;
}
public void add(E element) {
//logic to add the element in the array...
this.size++;
}
}
In this example, you can see that the size value can change only inside the class methods, and you can get the actual size by calling it in your code (not mutating it):
public void someMethod() {
List<String> ls = new ArrayList<String>();
//adding values
ls.add("Hello");
ls.add("World");
for(int i = 0; i < ls.size(); i++) {
System.out.println(ls.get(i));
}
}
Getters and setters encapsulate the fields of a class by making them accessible only through its public methods and keep the values themselves private. That is considered a good OO principle.
Granted, it often seems like redundant code if it does nothing more than setting or returning a value. However, setters also allow you to do input validation or cleanup. Having that in one place improves data integrity for your objects,
Because we are using Object oriented programming language.
Here we are using Data hiding and encapsulation.
The variable should not directly accessible from out side world (for achiving data hiding) so we will create it private so
shape.x
is not correct.
Getter and setter method are used to get and set the value of x which is the way to achive encapsulation.

Java tool for testing private methods?

There are different opinions on the meaningfulness of testing of private methods, e.g., here and here. I personally think it makes sense, the question is how to do it properly.
In C++ you can use a #define hack or make the test class friend, in C# there's the InternalsVisibleToAttribute, but in Java we either have to use reflection or to make them "visible for testing" and annotate them as such in order to make the intent clear. The disadvantages of both should be quite clear.
I think there should be something better. Starting with
public class Something {
private int internalSecret() {
return 43;
}
}
it would be nice to be able to call private methods in the test code like
#MakeVisibleForTesting Something something = new Something();
Assert.assertEquals(43, something.internalSecret());
Here the annotation would silently convert all calls to private methods of something using reflection. I wonder if Lombok could do it (and will ask the authors).
It's quite possible that doing that much magic proves too complicated, and in any case it'll take some time, so I'm looking for some alternative. Maybe annotating the class under test with something like #Decapsulate and using an annotation processor to generate a class Decapsulated_Something looking like
public class Decapsulated_Something {
public Decapsulated_Something(Something delegate) {
this.delegate = delegate
}
public boolean internalSecret() {
// call "delegate.internalSecret()" using reflection
}
...
}
which would allow to use
Decapsulated_Something something = new Decapsulated_Something(new Something());
Assert.assertEquals(43, something.internalSecret());
I don't have much experience with annotation processing, so I ask first here:
How complicated is this to implement?
What did I forget?
What do you think about it in general?
It seems like a lot of trouble to do this implementation. It may not be worth it. Rather just make the method package default.
However, if you are determined to call private method, you can use setAccessible in yourDecapsulated_something class to allow call via reflection. So it's fairly simple.
it would be nice to be able to call private methods in the test code like
#MakeVisibleForTesting Something something = new Something();
Assert.assertEquals(43, something.internalSecret());
There's such thing as a method annotation, check out dp4j's #TestPrivates:
#Test
#TestPrivates
//since the method is annotated with JUnit's #Test this annotation is redundant.
// You just need to have dp4j on the classpath.
public void somethingTest(){
Something something = new Something();
int sthSecret = something.internalSecret();
Assert.assertEquals(43, sthSecret); //cannot use something.internalSecret() directly because of bug [dp4j-13][2]
}
There are number of approaches to take
Don't test private methods as they are hidden implementation details which should never make a difference to the caller.
Make the methods package local so a caller cannot access them, but you can access them in the same package i.e. a unit test.
Make the unit test an inner class or provide a package local inner class. Not sure this is an improvement!
Use reflection to access the methods of the class. This is like marking a method rpivate when its not and is a confusion IMHO. You should be only marking a method private when it is truely private.
I'll answer the "In general" question :-) It only takes a few lines of code to make a method accessible via reflection and there are quite a number of libraries, utils, APIs etc that provide methods for doing so. There's also probably many different techniques you could use in your own code. For example bytecode manipulation, reflection, class extensions, etc. But I'd be inclined to keep things simple. Whilst it can be useful to test private methods, it's also likely that you will only want to test a few. So engineering something complex is probably overkill. I'd just use an established API, or write a quick method to access the private methods I was interested in and let it be done at that.
I worked on a project a few years back that generated classes to make it easier to unit test private methods. http://java.net/projects/privateer/
It generated extra classes that made it easier than calling reflection, e.g. if you had MyClass.myPrivateMethod() it would generate a _MyClass class that would allow invocation of myPrivateMethod directly.
It was never really finished and was kind of useful for a few cases, but overall I wouldn't recommend testing private methods unless absolutely necessary. Usually redesigning them into utility classes (with package access if you're worried about users using them) is a better option.

Question on the nature of inherited Java classes

So I think I have a pretty basic question. Say there's an open source Java program called com.cow.moo that you include in your project com.bee.buzz.
moo has a bunch of great classes, most of which you don't want to touch, but there are a couple you do. Now at this point, the best thing to do would be to extend the classes you want to modify, right? (I know there's been a lot said of extends vs. implements, but none of these classes are interfaces, so that's kind of out of the question.)
My question is, say this is the class in moo:
package com.cow.moo;
public class Milk {
private float currentMilk;
public int getMilk() { /* Stuff */ }
public float convertToGallons (float liquid) { /* More Stuff */ }
}
Now, say I want to just use getMilk in my new class that extends Milk. However, getMilk in Milk relies on private variables (like currentMilk) and other functions I won't be including (like convertToGallons.) Will I have to include those other variables and functions if I want my new function to work correctly? I don't want to heavily modify the function, just add a little bit to it. What's the best way to do this?
Tips in general in building off a larger project would be useful, too. I figure it won't even take five seconds for some of the Java experts here to come up with an answer. Thanks for your time.
The general recommendation is to favor composition over inheritance.
Say, you have an interface and an existing implementation that mostly fits you needs, like
public interface MilkProvider { public float getMilk(); }
public class Milk implements MilkProvider { // same as you example }
and need another custom implementation, you could code it like that:
public class MyMilk implements MilkProvider {
private MilkProvider milk;
public MyMilk(int someValue) {
milk = new Milk(someValue); // unfortunatly we can't get rid of a depencency
// to the concrete class because we need to create
// something. An existing factory could help, but
// but usually there's none implemented.
}
public float getMilk() {
float result = milk.getMilk();
// do somethink with the result
return float;
}
}
Now, say I want to just use getMilk in my new class that extends Milk. However, getMilk in Milk relies on private variables (like currentMilk) and other functions I won't be including (like convertToGallons.) Will I have to include those other variables and functions if I want my new function to work correctly?
You won't have to include the public functions and variables. The core concept of inheritance is that, as a subclass, you get all of your parent class's public (and protected) members included in your subclass for free. So your subclass (let's say HoneyMilk) can call convertToGallons right from the get-go.
Overriding getMilk in this case is a lot trickier, since it relies on a private variable (which your subclass cannot access). My advice is to shift your mindset from treating the class as a "white box" to a "black box". What I mean by that is that you should implement your overridden version of getMilk as if you weren't actually able to see Milk's source code. While it may seem like a roundabout solution (I mean, why can't I just go tweak this line here?!), this will force you to implement your subclass using only what the parent class exposes publicly. It also heavily emphasizes the importance of abstraction, which is absolutely crucial to utilize when developing large-scale projects.
I think in this case better solution will be polymorphism (static polymorphism), or you can use reflection (do not use this way) to reach to the private variable.
You can extend the class and access instance variables throught method accessors (getters & setters) if they are public.
You can use AOP (Aspect Oriented Programming) to change your moo classes at runtime without changing its sources.
Consider too read some Composition vs. Inheritance topics.
Hope this will help you.
You won't be able to use private class members unless you use Java reflection which will be kind of ugly. If I were you (and the changes are not too heavy, in which case I'd fork the original project), I'd look at modifying the code at runtime or statically using aspect weaving (aspect oriented programming). AspectJ may look as if it had a sharp learning curve, but it's a great tool to have in your toolbox and perfectly matches your needs here.

Categories