Casting to parent changes object reference? - java

I'm doing some work with jesque, workers and pipelines. I'm ok with that; the thing is that I have a new feature. I have a class named FileAnalysis, so it has some common attributes, but it is not abstract enough; it is still very focused on the task it was made for.
I made another feature before and was able to reuse this FileAnalysis. But this time there are new key properties for the feature I'm working on, so I created a new object ContactFileAnalysis with the additional properties.
A FileAnalysis consists of the main object, which is then parsed to JSON and stored in redis. This is done through a manager; this manager reads/writes to redis, and recreates the FileAnalysis object. There is a support object to update the state of the file analysis in a pipeline; it's called:
FileAnalysisUpdater(FileAnalysis).
If I make a new manager which is able to handle ContactFileAnalysis, this objects holds new properties and the new manager will store them in redis correctly. Then it calls the updater in a pipeline. What I want to achieve is to invoke
ContactFileAnalysis contactFileAnalysis;
updater.Update((FileAnalysis) contactFileAnalysis);
When I cast to a parent object and the pipeline is done, will contactFileAnalysis be updated by the updater? Or does this cast change the object reference and therefore no change is reflected?
I want to reuse this functionality because there are no changes in it; the behavior is the same, the information is the same; I just need to propagate new information, and to do so I persist it in redis, but from there on it's the same; the updater doesn't need anything from my new object.
P.S.: I know it is safer to write every involved object again and make sure it works with the new FileAnalysis, but this means a lot of code for a feature that is hardly used and not that important. Also, I work for this project and it's not easy to approve a PR of 4k lines of code.

As user2864740 pointed out in a comment, casting an object reference never changes the reference. You can test this easily enough:
Object obj = null;
String str = "foo";
obj = (Object) str; // Unnecessary! See below.
System.out.println ("Is str == obj? " + (str == obj));
However, that casting to the parent is likely unnecessary. Hopefully you declared ContactFileAnalysis to be a subclass of FileAnalysis:
public class ContactFileAnalysis extends FileAnalysis
If so, then any reference to an instance of ContactFileAnalysis is always considered a reference to an instance of FileAnalysis. In fact, it's also a reference to an instance of FileAnalysis' superclass, and so on up the line (to java.lang.Object, the parent of all java objects). Which means my cast to Object in the sample code was unnecessary:
obj = str; // This works, and is considered proper style.
It's also unnecessary to cast it to pass it to updater.Update(). (Another style note: methods should start with a lowercase letter.)
updater.Update(contactFileAnalysis); // Probably fine. See below.
Note that if you didn't declare ContactFileAnalysis to be a subclass of FileAnalysis, you will have to cast it. (This could happen if you instead had a class that implemented two interfaces, had a reference to an instance of it typed to one of those interfaces, and wanted to pass it to a method that took an instance of the other.)
Another note: if for some reason you had two methods as follows:
public void update (FileAnalysis fa) { /* code */ }
public void update (ContactFileAnalysis cfa) { /* ugh */ }
And you made a reference to a ContactFileAnalysis instance, and passed that to your updater:
ContactFileAnalysis myCFA = new ContactFileAnalysis();
updater.update (myCFA);
It'll use the second update - the one defined to take a CFA. Cast it, however:
updater.update ((FileAnalysis) myCFA);
and it'll use the first update. Same thing happens if you set a FileAnalysis variable to it.
FileAnalysis myFA = myCFA;
updater.update (myFA); // uses the first update, even though it's a CFA
Hopefully you understand why. If not, check out the official documentation on inheritance.

Related

How to test the argument passed in the object creation by new operator

I want to test the argument passed in the constructor, e.g.:
class A {
public void function (String arg1, String arg2) {
C c = new C(arg1, arg2);
//....
}
}
In this, I want to test the arg1 value which is being passed while creating object of class C. Is there a way of doing this without using PowerMock?
In essence, without some kind of mocking framework, unless you are either returning the result of the newed object (either here or in a factory), or storing it in a field for later reference, you cannot directly test that those values are passed to that constructor. If there is something that indirectly makes use of that instance, you have a chance of testing it there, but that greatly dilutes the point of the test.
That being said, this is a very strange use case. If you're newing an object and not doing anything with it, what's the point of creating the new instance in the first place? The design and code flow of this particular piece of code should be called in question when sitting down to write tests like this.
If you really want to keep it around, move its creation to its own function, where you can independently test it. You would essentially be creating a factory which would allow you to supply new instances of C wherever you needed it.

Shared instance variable vs local variable

Is there a reason to prefer using shared instance variable in class vs. local variable and have methods return the instance to it? Or is either one a bad practice?
import package.AClass;
public class foo {
private AClass aVar = new AClass();
// ... Constructor
public AClass returnAClassSetted() {
doStuff(aVar);
return avar;
}
private void doStuff(AClass a) {
aVar = a.setSomething("");
}
}
vs.
import package.AClass;
public class foo {
// ... Constructor
public AClass returnAClassSetted() {
AClass aVar = new AClass();
aVar = doStuff();
return aVar;
}
private AClass doStuff() {
AClass aVar1 = new AClass();
aVar1.setSomething("");
return aVar1;
}
}
First one makes more sense to me in so many ways but I often see code that does the second. Thanks!
Instance variables are shared by all methods in the class. When one method changes the data, another method can be affected by it. It means that you can't understand any one method on its own since it is affected by the code in the other methods in the class. The order in which methods are called can affect the outcome. The methods may not be reentrant. That means that if the method is called, again, before it finishes its execution (say it calls a method that then calls it, or fires an event which then a listener calls the method) then it may fail or behave incorrectly since the data is shared. If that wasn't enough potential problems, when you have multithreading, the data could be changed while you are using it causing inconsistent and hard to reproduce bugs (race conditions).
Using local variables keeps the scope minimized to the smallest amount of code that needs it. This makes it easier to understand, and to debug. It avoids race conditions. It is easier to ensure the method is reentrant. It is a good practice to minimize the scope of data.
Your class name should have been Foo.
The two versions you have are not the same, and it should depend on your use case.
The first version returns the same AClass object when different callers call returnAClassSetted() method using the same Foo object. If one of them changes the state of the returned AClass object, all of them will get see the change. Your Foo class is effectively a Singleton.
The second version returns a new AClass object every time a caller calls returnAClassSetted() method using either the same or different Foo object. Your Foo class is effectively a Builder.
Also, if you want the second version, remove the AClass aVar = new AClass(); and just use AClass aVar = doStuff();. Because you are throwing away the first AClass object created by new AClass();
It's not a yes/no question. It basically depends on the situation and your needs. Declaring the variable in the smallest scope as possible is considered the best practice. However there may be some cases (like in this one) where, depending on the task, it's better to declare it inside/outside the methods. If you declare them outside it will be one instance, and it will be two on the other hand.
Instance properties represent the state of a specific instance of that Class. It might make more sense to think about a concrete example. If the class is Engine, one of the properties that might represent the state of the Engine might be
private boolean running;
... so given an instance of Engine, you could call engine.isRunning() to check the state.
If a given property is not part of the state (or composition) of your Class, then it might be best suited to be a local variable within a method, as implementation detail.
In Instance variables values given are default values means null so if it's an object reference, 0 if it's and int.
Local variables usually don't get default values, and therefore need to be explicitly initialized and the compiler generates an error if you fail to do so.
Further,
Local variables are only visible in the method or block in which they are declared whereas the instance variable can be seen by all methods in the class.

Using superclass type for subclass instance

I know this question has been asked a lot, but the usual answers are far from satisfying in my view.
given the following class hierarchy:
class SuperClass{}
class SubClass extends SuperClass{}
why does people use this pattern to instantiate SubClass:
SuperClass instance = new SubClass();
instead of this one:
SubClass instance = new SubClass();
Now, the usual answer I see is that this is in order to send instance as an argument to a method that requires an instance of SuperClass like here:
void aFunction(SuperClass param){}
//somewhere else in the code...
...
aFunction(instance);
...
But I can send an instance of SubClass to aFunction regardless of the type of variable that held it! meaning the following code will compile and run with no errors (assuming the previously provided definition of aFunction):
SubClass instance = new SubClass();
aFunction(instance);
In fact, AFAIK variable types are meaningless at runtime. They are used only by the compiler!
Another possible reason to define a variable as SuperClass would be if it had several different subclasses and the variable is supposed to switch it's reference to several of them at runtime, but I for example only saw this happen in class (not super, not sub. just class). Definitly not sufficient to require a general pattern...
The main argument for this type of coding is because of the Liskov Substituion Principle, which states that if X is a subtype of type T, then any instance of T should be able to be swapped out with X.
The advantage of this is simple. Let's say we've got a program that has a properties file, that looks like this:
mode="Run"
And your program looks like this:
public void Program
{
public Mode mode;
public static void main(String[] args)
{
mode = Config.getMode();
mode.run();
}
}
So briefly, this program is going to use the config file to define the mode this program is going to boot up in. In the Config class, getMode() might look like this:
public Mode getMode()
{
String type = getProperty("mode"); // Now equals "Run" in our example.
switch(type)
{
case "Run": return new RunMode();
case "Halt": return new HaltMode();
}
}
Why this wouldn't work otherwise
Now, because you have a reference of type Mode, you can completely change the functionality of your program with simply changing the value of the mode property. If you had public RunMode mode, you would not be able to use this type of functionality.
Why this is a good thing
This pattern has caught on so well because it opens programs up for extensibility. It means that this type of desirable functionality is possible with the smallest amount of changes, should the author desire to implement this kind of functionality. And I mean, come on. You change one word in a config file and completely alter the program flow, without editing a single line of code. That is desirable.
In many cases it doesn't really matter but is considered good style.
You limit the information provided to users of the reference to what is nessary, i.e. that it is an instance of type SuperClass. It doesn't (and shouldn't) matter whether the variable references an object of type SuperClass or SubClass.
Update:
This also is true for local variables that are never used as a parameter etc.
As I said, it often doesn't matter but is considered good style because you might later change the variable to hold a parameter or another sub type of the super type. In that case, if you used the sub type first, your further code (in that single scope, e.g. method) might accidentially rely on the API of one specific sub type and changing the variable to hold another type might break your code.
I'll expand on Chris' example:
Consider you have the following:
RunMode mode = new RunMode();
...
You might now rely on the fact that mode is a RunMode.
However, later you might want to change that line to:
RunMode mode = Config.getMode(); //breaks
Oops, that doesn't compile. Ok, let's change that.
Mode mode = Config.getMode();
That line would compile now, but your further code might break, because you accidentially relied to mode being an instance of RunMode. Note that it might compile but could break at runtime or screw your logic.
SuperClass instance = new SubClass1()
after some lines, you may do instance = new SubClass2();
But if you write, SubClass1 instance = new SubClass1();
after some lines, you can't do instance = new SubClass2()
It is called polymorphis and it is superclass reference to a subclass object.
In fact, AFAIK variable types are meaningless at runtime. They are used
only by the compiler!
Not sure where you read this from. At compile time compiler only know the class of the reference type(so super class in case of polymorphism as you have stated). At runtime java knows the actual type of Object(.getClass()). At compile time java compiler only checks if the invoked method definition is in the class of reference type. Which method to invoke(function overloading) is determined at runtime based on the actual type of the object.
Why polymorphism?
Well google to find more but here is an example. You have a common method draw(Shape s). Now shape can be a Rectangle, a Circle any CustomShape. If you dont use Shape reference in draw() method you will have to create different methods for each type of(subclasses) of shape.
This is from a design point of view, you will have one super class and there can be multiple subclasses where in you want to extend the functionality.
An implementer who will have to write a subclass need only to focus on which methods to override

making a class immutable in java

To make a class immutable what I can do is:
1)Make class final
2)do not provide setters
3)mark all variables as final
But if my class has another object of some other class then , somone can change value of that object
class MyClass{
final int a;
final OtherClass other
MyClass(int a ,OtherClass other){
this.a = a;
this.other = other;
}
int getA(){
return a;
}
OtherClass getOther(){
return other;
}
public static void main(String ags[]){
MyClass m = new Myclass(1,new OtherClass);
Other o = m.getOther();
o.setSomething(xyz) ; //This is the problem ,How to prevent this?
}
}
A) Make the OtherClass immutable as well
or
B) Don't allow direct access to the OtherClass object, instead providing only getters to act as a proxy.
Edit to add: You could make a deep copy of OtherClass and return a copy rather than the original, but that generally isn't the type of behavior you would expect in Java.
Immutability is best considered from the perspective of the API user. So your object API needs to satisfy the following two conditions:
No way for an external user to change the value of the object
A guarantee that any time the user reads or makes use of the object's value in the future, it will get the same result
Important note: It is in fact OK to have mutable data inside an immutable object as long as it behaves as an immutable object from the perspective of the API user. Consider java.lang.String for example: although it is generally considered as the definitive immutable class, it does in fact have a mutable internal field for caching the hashCode (not many people know this!).
So to address your question, if you wish to contain another (mutable) object inside an immutable object then you typically need to do one or more of the following:
Guarantee that nobody else can change the value of the mutable object. Typically this means ensuring that no-one else can have a reference to the mutable object, so this is only usually possible if you create the object yourself rather than accept a reference from outside.
Take a defensive deep copy of the mutable object, and don't hand out references to the new copy. Only allow operations that read the new copy in the public API. If you need to hand out a reference to this object, then you need to take another defensive copy (to avoid handing out a reference to the internal copy).
Use an immutable wrapper for the mutable object. Something like Collections.unmodifiableList. This is useful if you want to hand out a reference to the internal mutable object but don't want to run the risk of it being modified.
All of these solutions are a bit hacky - a better solution overall is to avoid the use of mutable objects within immutable objects. In the long run it's asking for trouble because sooner or later a mutable reference will leak out and you will have an extremely hard to find bug. You are better moving towards a full hierarchy of immutable objects (the approach taken by languages like Scala and Clojure)
I assume OtherClass (by the way you say Other once) is meant to be a class you don't control, or which has to have a setter.
If you can't remove getOther, change it to getOtherView and return a read-only view of other. There will be wrappers for all the get methods, but no set ones.
Return deep clones from your getters. You may find this to be no easy task.
All the objects referenced in the immutable class should be immutable, or at least be encapsulated as private and making sure that they are not modified (not inside the methods of your class and definitely not from the outside). For instance, if you have this situation:
public class MyImmutable {
private MutableClass mutableObject;
}
... You can not provide the getMutableObject() method, because doing so will open the door for outside modifications, like this:
myImmutable.getMutableObject().setSomeAttribute(newValue);
As a special case of the above, all collections and/or maps should be made immutable, with the ummodifiableXXX() methods in the Collections class.
you cannot (reasonably) stop that in java. if you don't have control over the other class, there are ways to effectively get immutable behavior, but it can be very expensive in practice. basically, you must always return a copy of that class in any public method return values. (the jdk actually has this problem with the TimeZone class).
But If my class has another object of some other class then , somone
can change value of that object...
Java objects are not primitive. If you mark a primitive as final, then its value cannot be changed once it is assigned. However, object contents cannot be final, only object references can be final. So you cannot make an object in this way.
One solution might be abandoning all setter/mutator methods those could change the particular fields of the object and encapsulating them in a way that you can only access them, not change them.
It is possible to create the immutable class in java by following ways
1.Don't Provide setter methods.
2.Make all fields are as final and private.
3.Make Class as final.

modify value in variable

I have a problem with one class in java
this class is public and extends of DefaultHandler
all method of this class are public too ... but the variables are private...
My problem is that if I copy the value in other variable and modify this second variable the first change too.
is like static variables.. but they are no static... any idea!!!
thanks in advance
This is because you are actually modifying the same object. For instance, if you have
Object obj = new Object();
Object obj2 = obj;
You don't actually copy anything, you simply make obj2 "point" (not quite the right term, but it will work for now) to obj. Any changes to obj2 will be reflected in obj. Therefore, if you want to actually copy it, you need to physically create a new Object and then manually copy all of the values into the new creation. You could implement the prototype pattern to copy the object. Primitives don't behave this way so if you were to do the same thing with a double or an int for instance, it would behave the way you expect.
Does all of that make sense?
You are probably having a problem with passing by reference versus passing by value. This page explains what I mean http://www.cs.umd.edu/class/sum2004/cmsc420/sum4v3e01/node6.html.
You probably are copying a reference to a changeable object, not the object itself; so after the copy, you have two references to the same object. Changing that object through either reference will have the same effect.
I can't tell you how to copy the actual object because there's no generic way to do it, but many classes provide a copy constructor or some other way to duplicate themselves. If you need help with that you'd have to provide more details.

Categories