Instance variable verification - java

Reading effective java, it mentions that we need to validate method parameters as a good practice, throw exceptions for public and assert for private methods. But, do we need to take any measure against instance variable.
EG: (dont take example as a use case, main question is Do I need to validate instance var or Not ?. Example was used only for explaining what i mean to ask. )
class Tree {
private Node root;
public doSomething() {
TreeNode node = root;
}
}
Now lets say root was never initialized and doSomething() was called directly, it would result in NullPtrException.
Do we need to guard against it ? If yes then how ? If no then why not ?

How about:
if (root == null) {
throw new SomethingException();
}
TreeNode node = root;
Simply put, just perform a null check on the root variable, and if it is null then execute code accordingly to fix that problem or throw a new exception for it.

The established practice to check method parameters can be generalized to check correct usage of a class. In the given example it is illegal to call method doSomething() when the instance variable root has not yet been initialized.
If you want a best practice rule, it is not to generally check instance variables, but to check that a certain usage protocol of a class is obeyed. (Unless the class is written in a way that no particular protocol needs to be followed, which is usually the better option.) This check will of course typically involve checking instance variables.
In contrast to throwing an IllegalArgumentException after a negative method parameter check, a protocol violation should lead to an IllegalStateException.
In the given example an IllegalStateException should be thrown, because that instance is not in a state where doSomething() may be called.

Move any validation code of instance variables to constructors and setters so you check it whenver it will be set or changed and throw any Exceptions if input is invalid BEFORE the change is made.
this keeps the instance variables in a valid state at all times for fully constructed objects so you don't have to sprinkle extra validation everywhere else.

Related

Calling constructor from another constructor and illegal argument exception

for my two parameter constructor to call the four parameter constructor is it proper with what I have done(I am still learning). Also it is supposed to instantiate open interval so is that still correct? for the copy constructor how would I make a copy of the explicit value constructor? Also how do I throw an exception if memory has not been allocated for object being copied?
for the copy constructor how would I make a copy of the explicit value constructor?
There is no built-in in Java for this. You'd have to manually copy the fields you want to copy
public LetsCallThisClassInterval(LetsCallThisClassInterval other){
this(other.left, other.right, other.stuff)
}
But this class looks like it should be immutable, so there is no real need for a copy constructor.
Also how do I throw an exception if memory has not been allocated for object being copied?
That just does not happen in Java. Memory is managed for you, and if you get an object reference, it will have been properly allocated already.
Or are you talking about other being null in the above example?
In that case, you will get a NullPointerException automatically. If you prefer an IllegalArgumentException (debatable), you can add a null check:
if (other == null)
throw new IllegalArgumentException("other interval cannot be null");
Let me see if I get this right, you want to do a constructor inception? In this case what you would want to do is use the Constructor(//insert the variables that correspond); that should fix the problem.
Using "this" will make the constructor refer to itself, I mean the same method. For example it would be.
public Constructor(char leftsym, double left, double right, char rightsymb){
new Constructor(left, right);
}
Now as a side note, the Constructor class already exists between the core classes in Java, I suggest that if you want to simplify your life change your java class name such as Constructor_1 or something like that.
Good Luck

Where must the argument be checked

In my java code I need to call one method inside the other. The argument passed to suspendUserTestList must not be null. So the very simple question is where I must to check for null case: before passing the value or inside the second method?
Here are my methods:
public String suspendTest(Integer locationId, Integer userId) {
testManager.suspendUserTestList(userTestList, SUSPENDED_TEST_FREQUENCY, usersTestsSuspenSession);
}
public void suspendUserTestList(List<UserTest> userTestList, Integer frequency, Session session) throws MonitorUsException {
if (userTestList == null) {
throw new MonitorUsException("Error");
}
}
Short answer will be Depends.
Long answer is .......
After looking at your method implementation, you are throwing the exception if it is null. So you have to call the method before checking to receive that exception.
If you check before calling the method, you won't receive any exception and it just skip the call to that method and proceeds further.
If you are fine with not calling even if it is null, check for null and then only call the method.
It's definitely a good idea to check the inputs of every method. So if your suspendUserTestList() method expects a non-null parameter, it should check that the parameter is indeed non-null before using it.
It makes your method more self-contained and less dependent on its calling environment. It's also easy to read and to test in isolation.
Whether you then also check in the caller is not so straightforward to answer, it depends on a lot of factors. I'd go with whatever looks cleaner.
Generally speaking
Generally, you want to check for null where you actually use the object's methods or properties.
However if the calling method knows that the called method will not check for null (when you use a library for instance, you have no control of how the object you give will be used, but by inspecting the code you may see that no null check is made), then you have to either check for null or catch NullPointerExceptions.
In any case, you must make sure to catch the possible NullPointerExceptions in a given layer of your application (for instance a level where you can provide the information to the user, if there is a UI).
Particular case
In your own particular case, your two methods are public. Because both can be called from outside, you have to make sure that the null check is made at the lowest level (suspendUserTestList), because you may start to call the suspendUserTestList method from other places in your code. By putting the null check in suspendUserTestList, you make sure that all other possible future calls to this method will have the same null check logic.
There is no fixed rule, both places can be valid. Common sense is to do it in the called method so you write the logic ones and not in all places where you use the method. Probably throw an IllegalArgumentException to not add new types for a common case.
It's definitely ok to check inside the public method (it's called "precondition"). As for checking before the call, it depends how you are using this userTestList field. Probably it was initialized in the constructor (like userTestList = new ArrayList<>()) and never reassigned. Then no need to check it anywhere (better to declare it as final). On the other hand it can be passed in some setter like this:
public void setUserTestList(List<UserTest> list) {
this.userTestList = list;
}
In this case it's much better to add one more check in the setter. In any case it's better to do the checks as early as possible.

Why can't you call a method on a null pointer in Java?

In Go, it is OK to call a method on a null pointer so long as that pointer is never dereferenced:
type empty struct{}
func (e *empty) Allocated() bool { return e != nil }
(For runnable code, click here)
In Java, however, calling a method on a null pointer, even if the method never dereferences any member variables, still causes a null pointer exception:
class Test {
public boolean Allocated() { return this != null; }
}
Does anybody know why this behavior exists? Is there some advantage that it gives? Thoughts?
This is because all Java methods are virtual.
When you write someInstance.Allocated(), the runtime needs to check whether someInstance is actually of a derived type that overrides the method.
In theory, this restriction could have been relaxed for final or private methods.
I assume that the language designers chose not to for consistency. (and so that removing final wouldn't be a breaking change)
The answer by SLaks is good from a Java perspective. I don't have a clue about Java but I know Go and here's my answer:
First of all nil is not the same as a NULL pointer, there are some fundamental differences.
Then, methods in Go are not part of a type's instance but the type itself i.e. Go does not store the vtable inside objects, like Java does:
var e *empty
fmt.Println(e.Allocated())
is the same as… (syntactic sugar for…):
var e *empty
fmt.Println((*empty).Allocated(e)) // This is valid code
Note how Allocated is invoked as a member of *empty, much like a static method in traditional "OOP" languages.
In fact, (*empty).Allocated is just a function name with a weird notation that includes a dot, an asterisk and parens.
Because the receiver is just another argument, the fact that it is nil is unimportant to the method dispatch mechanism.
In Go, it is OK to call a method on a null pointer so long as that pointer is never dereferenced
If by OK you mean legal, then it's even OK to call a method on a nil value and dereferencing it. The compiler won't complain - you'll just get a runtime panic.
I think it's a philosophical issue; methods (except for static methods) apply to an object, by their very nature, and calling a method like that on a non-object like "null" just doesn't make sense in this paradigm. If you want to define a method that can apply to an object or to "null", it's easy enough to define a static method that does that, and in my opinion that would make the code that calls the method less confusing to readers.

Instantiate objects in initialization?

I have a class that holds another objects inside it (List, Set and objects from my application).
public class SomeClass {
private List l;
private SomeObject obj;
//...
}
Is a good practice instantiate these objects where the SomeClass object is created to avoid NullPointerException? Something like:
public class SomeClass{
private List l = new ArrayList();
private SomeObject obj = new SomeObject();
//...
}
In a normal way, these objects will be generated in some processing/analysis, but errors can occur and the objects still with null value.
Yes, it is a good practice to do so. The constructor is a natural place to instantiate member objects. You can also create them right where they are declared:
private List l = new ArrayList();
However, it might be a good idea to restructure or modify your code so that NullPointerExceptions won't occur, regardless of the order in which the methods are called.
If an empty List or a default object of that class is a valid state in every following operation, yes, instantiate a default. However, if the default would be an invalid state, don't do it.
Well I prefer to initialize because sometimes is a headache to find where's the null pointer exception, and if u initialize your objects with constructors the object inside should be initialized.
Hope this help you.
It's generally good practice to instantiate member fields (whether objects or primitives) at creation time whenever the default value (0, false, or null) is not what you want. One time to defer this is for lazy instantiation. (This is used, for instance, when an object might not be needed after all and creating it is expensive.) Another time to defer this is when other initialization needs to take place beforehand.
Assuming you want to initialize a field at object creation time, there are two ways to do it: with an initializer expression as you showed or in the constructor(s). There isn't too much difference, other than that instance initializers run before the first line of the constructor. This may or may not cause problems, depending on your code logic.
It's also a good idea to declare member fields final whenever they are initialized at object creation and are expected to not change during the life of the object. A side benefit of declaring a field final is that the compiler will catch any failure to initialize it. (The compiler requires definite assignment to consider a final field to be properly initialized.)
You are talking about eager construction versus lazy construction. There are places where each has value.
In many situations, it is better to lazily create things as it saves memory. But then you must check for null every time you try to get data
In some situations, it makes sense to create the object upfront, either to avoid the null checking mentioned above or to avoid the object creation time hit during an intensive process
It is normal to generate them like this, but it's not a nice way to code to generate them just to avoid NPE. There should be proper validation in code, rather than assigning garbage-eligible objects which won't be utilized.
You can also assign some default states - like Collections.emptyList(), or
in a constants class:
DEFAULT_STATE = new SomeState();
then simply
class A {
State obj = Constants.DEFAULT_STATE;
}

Is IllegalStateException appropriate for an immutable object?

Would you throw an IllegalStateException if:
A method is unable to do its job because of the value(s) of one or more fields
Those fields are final and assigned only in the constructor?
Textbook example: your class is an immutable Collection<BigInteger> and your method is supposed to return the maximum element, but this instance is empty.
I have read Kevin Bourillon`s blog post on the subject and I am not sure which rule applies.
UnsupportedOperationException - this means that the method invoked will always fail for an instance of this class (concrete type), regardless of how the instance was constructed.
Definitely not. Many instances of this class are not empty and the operation would have succeeded.
IllegalStateException - ... there does exist at least one alternate state that the instance in question could have been in, which would have passed the check ... <snip> ... Note also that this exception is appropriate whether or not it is possible to actually mutate this aspect of the instance's state, or it's already too late.
Not quite. This instance was constructed with zero length, so this instance is not and could never have been non-empty.
IllegalArgumentException - throwing this exception implies that there exists at least one other value for this parameter that would have caused the check in question to pass.
Might apply if the parameter in question is the implicit this parameter. This is the exception I am tempted to throw, but I am concerned that it could be confusing.
Update: changed example from Collection<Integer> to Collection<BigInteger> because the fact that there was an identity element (Integer.MIN_VALUE) distracts from the question.
It doesn't sound like any of the common exception classes you mention above fit into the Textbook example.
You should throw a NoSuchElementException as that's exactly what the Collections.max() method does.
I think IllegalStateException is appropriate here. The instance could have been in the correct state, if it was constructed correctly (i.e. the "it's already too late" part).
If the state of the class is valid (empty collection), the max element is just null. If the state is not valid, an IllegalArgumentException should have been thrown at construction time.
IllegalStateException comes closest to what you want: "this exception is appropriate whether or not it is possible to actually mutate this aspect of the instance's state".
Not UnsupportedOperationException, since it might succeed for some instance of that class, and throwing IllegalArgumentException for a method that (presumably) takes no arguments will certainly confuse people.
Is IllegalStateException appropriate for an immutable object?
No, because immutable objects only have one state, and could not have pased from one legal state to another.
So, you're constructing an immutable object, and your object should have a max method
class YourObject {
public BigInteger max(){ ... }
}
I this case IllegalAgumentException should be the correct, but not until the method is executed, but when the object is created!
So, in this scenario, if you have an immutable collection of bigintegers, and you create it with zero elements you are receiving an "invalid argument" upon the collection creation, that's when you have to throw the exception.
I agree with Jon, if your use case, or in you analysis, you're willing to support the rest of the operations, you could throw NoSuchElementException, but I think that would be to postpone the problem. Better would be to avoid the object creation in first place.
So, throwing IllegalArgumentException would be like:
// this is my immutable object class
final class YourObject {
private final Collection<BigInteger> c;
public YourObject( BigInteger ... values ) {
if( values.length == 0 ) {
throw new IllegalAgumentException("Must specify at least one value");
}
... initialize the rest...
}
public BigInteger max() {
// find and return the max will always work
}
}
Client:
YourObject o = new YourObject(); // throws IllegalArgumentException
// the rest is not executed....
doSomething( o ) ;
...
doSomething( YourObject o ) {
BigInteger maximum = o.max();
}
In this case you don't need to check for anything in doSomething because the program would fail at the instance creation, which in turn would be fixed at development time.
Throwing NoSuchElementException would be like:
final class YourObject {
private final Collection<BigInteger> c;
public YourObject( BigInteger ... values ) {
// not validating the input :-/ oh oh..
... initialize the rest...
}
public BigInteger max() {
if( c.isEmpty() ) { throw NoSuchElementException(); }
// find and return the max will always work after this line
}
}
Client:
YourObject o = new YourObject(); // it says nothing
doSomething( o ) ;
...
doSomething( YourObject o ) {
BigInteger maximum = o.max();// ooops!, why? what?...
// your object client will start questioning what did I do wrong
// and chais of if( o != null && o.isEmpty() || moonPhaseIs... )
}
Bear in mind, that, if a program is to fail, the best thing you can do is to making it fail fast.
Collections.max have a different purpose, because being an utility method (not an immutable object ), he cannot held responsibility for the empty collection creation ( he wasn't present when that happened ), the only thing he can do is to say "There is no such a thing as max in this collection" hence NoSuchElementException.
One last remark, RuntimeExceptions, should be used for programming mistakes only ( those that can be fixed by testing the application before releasing it )
You should thrown an UnsupportedOpertationException because that's what the Java Standard Library does in the same circumstance. Your example is a type qualifier object protocol. This pattern was defined in "An Empirical Study of Object Protocols in the Wild":
Some types disable certain methods for the lifetime of
the object. In the type qualifier category, an object instance will enter an abstract state S at construction-time which it will never leave. Calls to an instance
method m, if it is disabled in state S will always fail.
In your example, your object enters an abstract state which I'll call EmptyCollection at construction time and it never leaves that state because the collection field is final. In the EmptyCollection abstract state all calls to the getMax() instance method will always fail.
Beckman studied open source Java programs looking for object protocols and categorized the resulting classes. The third most common protocol category, appearing in 16.4% of the protocols sampled, was type qualifier.
Beckman's paper lists many type qualifier examples and I selected three of them and in each case the unavailable method throws an UnsupportedOperationException:
When you create an unmodifiable list by calling Colections.unmodifiableList(...) and then call the add method on the resulting list.
When you create a java.nio.ByteBuffer that is not backed by an array and then call the array method.
When you create a java.imageio.ImageWriteParam that does not support compression and then call the setCompressionMode method.
Notice that these examples do not follow Kevin Bourillon's advice that you cite. The failure of these methods is dependent on how the instances were constructed. In examples 1 and 2 the instances that succeed and fail may be of different concrete classes since List and ByteBuffer are abstract. However, ImageWriteParam is a concrete class so one instance of ImageWriteParam may throw the UnsupportedOperationException while another one may not. Since the Java Standard Library designers also defined the exception types I would follow their lead instead of Mr. Bourillon's.
P.S. You should use IllegalStateException when instead the abstract state of your object can change at runtime. The other 83.6% of the examples in Beckman's paper are of this type.

Categories