Safeguarding method parameters in java - java

I want to safe guard my method parameters that were passed to the called method from being changed accidentally. I know that we can use final keyword to achieve this (partially) like the following in the method signature.
public void someMethod(final int intVal, final MyClass myobj){}
With the help of the above signature I cannot change the value of intVal, but however I can change the values (members) of myobj (I can safe guard only the reference not being changed, but not the members of the referencing object, that why I said partial).
Now I am looking to safe guard my myobj members either, getting changed in the called method someMethod.
In my knowledge I could achieve this using the following ways
Create an immutable class and pass it as a parameter
Deep copy the object and send the cloned object to the method.
Is there any better apporach to safeguard the method parameters?

Related

Const function arguments in java?

Is there a way to achive something similar to C++'s const in Java? Specifically, I have a function like
private static Vector2 sum(Vector2 vec1, Vector2 vec2) {
return vec1.cpy().add(vec2);
}
and I want to
make clear in the signature that it doesn't modify it's arguments,
and
enforce that it doesn't modify it's arguments (preferably at compile time, but inserting runtime assertions would also be OK).
Now I know that java is strictly pass-by-reference (I'm just teasing, I know it is pass-by-value or rather pass-by-copying-a-reference of course). What I mean is that in Java, when you call a method, the reference is copied, but that reference points to the same object contents. If a class has public fields or setters, a called method can always modify the contents of a passed object. Is there any e.g. annotation like #NotNull or tool to prevent this? I just found the JetBrains annotations like #Contract(pure = true), but I don't think they provide any checking.
You can not guarantee that method won't change the parameters. If you want to avoid changing the object, you should make it immutable. You can use some wrapper classes to be passed inside, without provided setters. Or you can make your setters package-local and use some access helper classes in the same package if you need to call some package-local method.
In Java the only way to do this is to have a read only interface as well as a mutable one. This isn't easy to maintain and a const would be much nicer, but it's not available. You can write
interface ReadOnlyVector<T> {
int size();
// getter methods
T get(int n);
default ReadOnlyVector<T> add(ReadOnlyVector<T> v) {
// add two vectors and create a new one.
}
}
interface Vector<T> extends ReadOnlyVector<T> {
// mutating methods.
void add(T t);
}
You can add final to the parameter, but this will only prevent a initialisation of those, you still can call method and setter modifying the content of your Vector.
If you need the restrict the access to those, you might need to create a immutable class hiding the Vector, a wrapper. Basicly it will redirect only the methods that prevent any update by hiding the setter and limit the getter to primitive values, returning an instance give a possibility to change a value in it.
Of course, there is also some drastic solution, you could clone the Vector and his content. Keeping the instances safe even if someone try to update some values. This will only be a problem during this call, using wrong values but will keep the original instances unchanged.
Or you could use both solution, creating a wrapper that return cloned instance (just need to provide a get(int index) that return a clone). This solution is a compromise between memory consumption (cloning only needed instance) and restrictive getter.

Java: instance variable vs. local parameters

I am puzzled by this:
private RenderingHints hints;
public void addRenderingHints(Map hints) {
hints.putAll(hints);
}
(from http://dev.geogebra.org/trac/browser/trunk/geogebra/desktop/org/freehep/graphicsio/AbstractVectorGraphicsIO.java?rev=39574#L1238)
Both Map and RenderingHints have a putAll member functions:
https://docs.oracle.com/javase/8/docs/api/java/awt/RenderingHints.html#putAll-java.util.Map-
https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#putAll-java.util.Map-
I have learned that local parameters can shadow instance variables. So what does this part of code do (useful)?
The code is wrong. Currently, it adds the elements of the parameter Map hint in itself, that will end doing nothing.
The code should be:
public void addRenderingHints(Map hints) {
this.hints.putAll(hints);
}
The difference is when using this.hints. Using this refers to the fields in the class.
It adds contents of the Map referenced by the parameter to itself. That is, it calls putAll on the parameter, passing the parameter in. The instance member is not involved at all.
This is not likely what was intended. They probably meant:
this.hints.putAll(hints);
That calls putAll on the instance field, passing in the parameter.
This is one reason why some Java lint tools and IDEs have an option to require that you prefix instance fields and methods with this., even though the language specification makes it optional (er, when they're not shadowed by local parameters). In any case, hopefully any decent IDE would warn you that the parameter was shadowing the instance field.

Best design approach for creating Immutable Class

I am reading about the specific guidelines that needs to be followed while creating Immutable Class in Effective Java.
I read that In Immutable class method should not allowed to be overridden otherwise overridden method may change the behaviour of method. Following are the design approaches available in java to solve this problem :-
We can mark class final but as per my understanding, it has a one disadvantage that it makes the class inextensible.
Secondly is to make individual methods final but I can not get other disadvantage besides that we need to individually mark each method as final in order to prevent overridding.
As per book,better approach is to make the constructor private or package-private and provide public static factory method for creating object.
My question is: Even if we include private or default constructor in the class, it cannot be extended anymore in same package (in other package in case of package-private constructor), it has a same problem which the first one had. How is it considered as the better approach than the previous ones?
An immutable object should not be extensible. Why?
Because extending it will allow either direct access to fields (if they are protected which would allow writing methods that change them), or adding state which may be mutable.
Imagine we wrote a class FlexiblyRoundableDouble that extends Double, which has an additional field roundingMode that lets us choose a "rounding mode". You could write a setter for this field, and now your object is mutable.
You can argue that if all the methods are set as final, you cannot change the original behavior of the object. The only methods that could access your roundingMode field are new methods that are not polymorphically available if you assign your object to a Double variable. But when a class's contract says that it's immutable, you make decisions based on that. For example, if you write a clone() method or copy constructor for a class that has Double fields, you know that you don't need to deep-copy the Double fields, as they do not change their state, and can therefore be safely shared between the two clones.
Also, you can write methods that return the internal object without fearing that the caller will then change that object. If the object was mutable, you'd have to make a "defensive copy" of it. But if it's immutable, it's safe to return a reference to the actual internal object.
However, what happens if someone assigned a FlexiblyRoundableDouble to one of your Double fields? That object would be mutable. The clone() would assume it isn't, it will be shared between two objects, perhaps even returned by a method. The caller would then be able to cast it back as a FlexiblyRoundableDouble, change the field... and it will affect other objects that use that same instance.
Therefore, immutable objects should be final.
All this has nothing to do with the constructor issue. Objects can be safely immutable with public constructors (as demonstrated by String, Double, Integer and other standard Java immutables). The static factory method is simply a way utilizing the fact that the object is immutable, and several other objects can hold references to it safely, to create fewer objects with the same value.
Providing a static factory method gives you room to implement the Flyweight Pattern.
They're stating that you should hide the possibility of creating a new object using a constructor, and should rather make a call to a method which checks if an object with similar state exists in the "object pool" (a map filled with objects waiting to be re-used). Not re-using immutable objects is a waste of memory; this is why String literals are encouraged, and new String() is shunned (unless needed).
class ImmutableType {
private static final Map<Definition, ImmutableType> POOL = new HashMap<>();
private final Definition definition;
private ImmutableType(Definition def) {
definition = def;
}
public static ImmutableType get(Definition def) {
if(POOL.contains(def))
return POOL.get(def);
else {
ImmutableType obj = new ImmutableType(def);
POOL.put(def, obj);
return obj;
}
}
}
Definition stores the state of the ImmutableType. If a type with the same definition already exists in the pool, then re-use it. Otherwise, create it, add it to the pool then return it as the value.
As for the statement about marking the class final, immutable types should not be extensible in the first place (to avoid possibly modifying behavior). Marking every method final is just crazy for immutable classes.

Invoking dynamic Method without known Constructor?

If I do this in Java to call a method name from a class dynamically, it works.
MainApp app = new MainApp();
Method meth = app.getClass().getMethod("myMethod", MyParameterType.class);
//call method
meth.invoke(app, new MyParameterType("hello"));
But this worked because I know the constructor in the invoke method. But if I were to pass the Method object as a parameter to some other classes, and I don't know who is the constructor, I cannot invoke the method any more. Even if I know, I may not want to create a different object to just make a call to the method. For eg:
//This is in the class call MainApp.java.
//There is a method in MainApp.java that looks this way: myMethod(MyParameterType param);
MainApp app = new MainApp();
OtherClass myClass = new OtherClass();
Method meth = app.getClass().getMethod("myMethod", MyParameterType.class);
myClass.callMe(meth);
//Inside OtherClass.java
public void callMe(Method meth) {
//call method
meth.invoke(########, new MyParameterType("hello"));
}
In this case, what should I put for the ######## parameter? Within the context of OtherClass.java, the base constructor object wouldn't be known. And why would I need if since meth is already a Method type that I just call like a function?
Thanks
Assuming it's an instance method, you've got to have an instance to call the method on, just like anything else. How you get hold of that instance will depend on what you're trying to do; you could pass in a Constructor, or a reference to an existing object, or some interface which will create the instance when you ask it to... we can't really give you any advice on which approach is the most suitable without knowing what you're trying to do.
If it's a static method, you can pass null for the first argument.
What it seems you are looking for or thinking about is the concept of `lambda functions``. Those can be called in isolation.
A Method type is not a standalone method, but more like a 'path' into an object. Compare this with a relative URL like /subscribe.html. Out of context this is pretty useless, but when bundled with a site like www.example.com it makes sense.
As such, Method can only be used in combination with an instance. (edit: as John mentioned, unless it's a static method of course which do not need instances)
If you can safely invoke a method without providing an instance, it should be a static method, in which case any instance provided is ignored, you can give it null.
If you have to provide an instance of the object, there is no way around this.
If the developer who write the method has labelled it non-static incorrectly, I suggest you discuss with them why they did it.

How to store a reference to a class in Java?

Is there any way in Java to store a reference to a class? Here's what I want to do:
public class Foo
{
public static void doSomething() {...}
};
SomeClass obj = Foo;
obj.doSomething();
Is there some class "SomeClass" which lets me store a reference to a class, such that I can later use that stored object to call a static member of the original class?
The obvious thing would be class Class:
Class obj = Foo.class;
obj.someMember().doSomething();
but I haven't figured out which of class Class's members might act as "someMember()"... none of them, I think.
Does anyone know if what I'm trying to do is possible in Java?
You can dynamically get a method from a Class object using the getMethod() methods on the class. If a method is static, then the "object" parameter of "invoke" will be null.
For example, the "obj.someMember()" above would be something like this:
obj.getMethod("someMember", null).invoke(null, null);
The extra nulls are because your method requires no parameters. If your method takes parameters, then they will need to be passed in accordingly.
This will throw various checked exceptions, so you'll need to handle those as well.
Once you've invoked the method, it will return an Object. You'll want to cast that to whatever type you're expecting, and then you'll be able to run the "doSomething()" method directly on that.
This is using a trick called reflection, if you'd like to read up more on it. :)
If you are using jdk1.5 or above, annotation will be a choice when you want to get metadata of Class.

Categories