I'm not talking about checking if a boolean is null as a means to check if it is initialized. Because that won't work. So I thought this might work:
public class MyClass{
private boolean setting;
private boolean getSetting{
// get the setting;
}
public void main{
if (setting != (true && false))
setting = getSetting();
// do main stuff;
}
}
And it does! So my question is: would this be a good practice compared to the alternative, which would be the use of an extra variable:
public class MyClass{
private boolean initialized = false;
private boolean setting;
private boolean getSetting{
// get the setting;
}
public void main{
if (!initialized)
setting = getSetting();
initialized = true;
// do main stuff;
}
}
Booleans are a primitive type, therefore they do not need to be initialized. The default value for a boolean is false.
The first code sample returns false because the phrase true && false will always equate to false (&& checks whether both statements are true, which they aren't, so it is false) and then you check if setting, which is also false, is unequal to that, which it is not. An initialized variable could therefore be useful.
You can read more about defaults and primitive types here.
if (setting != (true && false)) doesn't do what you think it's doing.
The expression (true && false) always evaluates to false: you're doing a logical AND on the literal values true and false.
That means that your test reduces to if (setting != false). Since setting is not initialized, it defaults to false. When the code runs it checks if (false != false), which evaluates to false.
When I run the code you posted it does not call getSetting, as expected.
In your example, best practice would be to initialize the variable inside the constructor:
public class MyClass {
private boolean someSetting;
public MyClass() {
someSetting = getSetting();
}
private boolean getSetting() {
...
}
public void main() {
// By the time this is called we can guarantee that someSetting has been initialized correctly
// Do main stuff...
}
}
The issue with (setting != (true && false)) has already been discussed, but the real issue is that the primitive boolean only has its two obvious options. It's always either true or false. If both of those are meaningful answers, then that value cannot also indicate whether it's been initialized or not. An initialized, meaningful false will look the same as not having been initialized.
The best solution if it's available is, as Cameron Skinner answered above, to ensure the variable is always initialized by doing so either where it's declared or in the constructor. That, however, requires that the answer to what setting should be is known at the time the class is instantiated.
If the proper value is not necessarily known at that point and might need to be set later (so having been deliberately set to false is a different situation than having never been set), then you have a couple options:
One is as shown in the initial post, to have a separate initialized variable telling you whether it's happened or not. That might look a little clunky, but it works.
The other option is to use a Boolean object rather than a boolean primitive for setting. A Boolean object can be set to either true or false, but it initially defaults to null, so you can use a check for null to determine whether it has been set or not.
Related
I am dealing with some past exam papers and here I am not sure of the output. I think I am not clear about extends and super.
public class Superclass{
public boolean aVariable;
public void aMethod(){
aVariable = true;
}
}
class Subclass extends Superclass {
public boolean aVariable;
public void aMethod() {
aVariable = false;
super.aMethod();
System.out.println(aVariable);
System.out.println(super.aVariable);
}
}
I think that the second output would be true since it would refer to the super class and it is an object. However, I am not sure of the first output. Would it be just a value and print false or it is also an object?
The output will be:
false
true
Because in your Subclass aVariable is false by default (so assignation aVariable = false; is needless). Read more about Primitive Data Types default values.
And in Superclass you initialize aVariable as true by invoking the superclass' method using the keyword super: super.aMethod();. Read more about Accessing Superclass Members.
Take a look on demo.
Since they're both scoped to their own class block, having them with the same name doesn't matter. As it looks like now, you set aVariable to false, the call to the super doesn't change that, except for creating another variable (new reference) with the same name and sets it to true. So the expected output would be
false
true
Output will be:
false
true
super.aMethod() will execute making aVariable = true of SuperClass
aVariable of SubClass will remain false.
I conducted scientific experiment (copy-pasted and ran) and it prints
false
true
More here:
If you overwrite a field in a subclass of a class, the subclass has two fields with the same name(and different type)?
The following code for Integer uses object interning:
Integer.valueOf("1")
It is not clear from API documentation whether this code for Boolean also uses interned object:
Boolean.valueOf("true")
Obviously, it may. But does it have to?
UPDATE
I agree that source code can explain what actually happens (BTW, thanks for the answers). To make the question less trivial, is there any part of Java API spec or JSL which tells what MUST happen?
It was natural to ask the question against the code like this:
String str = "true";
if (Boolean.valueOf(str) == Boolean.TRUE) { ... }
The outcome depends on whether "object interning" is guaranteed or not. It's better to avoid this code altogether and use true instead of Boolean.TRUE (rather than looking up details in any specs or sources), but it is a valid reason to ask the question.
NOTE: In fact, I didn't see guarantees of object interning for Integer in any googled specs. So, it may all be just an implementation detail nobody should rely on.
The JLS guarantees that:
Integer i = 1;
Boolean b = true;
will use interning (at least between -128 and 127 for Integers, and for true and false for Booleans).
The relevant javadocs also guarantee that:
Integer i = Integer.valueOf(1);
Boolean b = Boolean.valueOf(true);
will return interned objects.
However there is no such explicit guarantees for valueOf(String): although it is the case in the specific implementation you are using, it may not be the case with a different JVM or in future releases. In fact an implementation that would return new Boolean(Boolean.parseBoolean(input)) would be valid.
Based on the source code, the boolean is parsed as:
public static final Boolean FALSE = new Boolean(false);
public static final Boolean TRUE = new Boolean(true);
public static Boolean valueOf(String s) {
return toBoolean(s) ? TRUE : FALSE;
}
Where TRUE and FALSE are static (immutable) objects. So yes, parsed booleans are interned.
However, I agree with #JBNizet's comment that one should not derive code contracts from the source code: as long as a feature is not documented, the developers of Java can change their mind. You better use Boolean.equals to check whether two objects are equivalent.
Here's the source code:
public static Boolean valueOf(String s) {
return parseBoolean(s) ? TRUE : FALSE;
}
Where TRUE is:
public static final Boolean TRUE = new Boolean(true);
If you're still not sure, define two variables:
Boolean a = Boolean.valueOf("true");
Boolean b = Boolean.valueOf("true");
and check whatever you want by yourself.
I am trying to write a boolean condition for genre fiction or non fiction for my program. However there is something wrong?
For the instance variable:
private boolean fiction, nonFiction;
or
private boolean Genre;
that compiles fine, but I don't know how to initialise this?
Genre = "";
No idea, I am a beginner to Java still learning.
Also I need to create a method which will give me true or false depending the input, can pointers be given so I can note how to create this method?
Java instance variables are automatically initialized either 0 (or equivalent) for numbers, null for objects, or false for booleans. So you don't need to explicitly do it. But you can, but you must provide something valid. eg.:
private boolean Genre = false;
You need to read up more in order to create functions, but the general signature should look like
<access qualifier> <return type> <method name>(parmeters ..){
// logic here
return <something with return type>;
}
eg.:
public boolean myFunction(int someparameter, int someotherparameter){
return true;
}
but I don't know how to initialise this?
boolean fiction = true;
There is no need to initialize boolean member to false, because that's its default value, so this is enough:
boolean fiction; // fiction is initialized automatically to false
also I need to create a method which will give me true or false depending the input, can pointers be given so I can note how to create this method?
boolean function(Object input) {
if (something) {
return true;
}
return false;
}
Can Boolean.valueOf(String) ever return null? From what I can see in the java docs, the docs only specify when it returns true. Is false always returned otherwise, or can null be returned? I have not been able to get it to return null in the tests I have done, but I would like to be sure.
Essentially, I want to know if the following code is safe from a NullPointerException:
boolean b = Boolean.valueOf(...);
The docs pretty much answer it: no. It'll return a Boolean representing a true or false.
The code is also available:
public static Boolean valueOf(String s) {
return toBoolean(s) ? TRUE : FALSE;
}
No, this is impossible. See the source code of the class Boolean:
public static Boolean valueOf(String s) {
return toBoolean(s) ? TRUE : FALSE;
}
.. and then:
private static boolean toBoolean(String name) {
return ((name != null) && name.equalsIgnoreCase("true"));
}
Actually it could cause NPE but can not return null. Try this:
Boolean bNull = null;
System.print(Boolean.valueOf(bNull)); // -> NPE!
This happens cuz Boolean.valueOf() accepts String or boolean values. Since bNull is of type Boolean java tries to unbox bNull value to pass it as boolean which causes NPE. Its funny but stupid actually... Also there is no Boolean.valueOf() for Number.
No it will not. If null is placed within the argument or if a string is set to null it will return a boolean value of false. You can see expected inputs and outputs in the Java docs: http://docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html#booleanValue()
This is maybe so silly.
I have a boolean variable inside the main method. By calling another method of this class or another class I want my boolean value to be modified in the main method. I do this but the change happens only in the called method(locally), not the caller(main). I think this is because of the pass-by-value feature of java.
I even tried Boolean type, but the same problem there!
Actually I'll use this to manage the ordering of concurrent threads. The main processor will check for the boolean value of every thread to see if it is ok to continue and tick the clock. After ticking the clock the main will make the vars false and will wait until the vars are again true. the sub-threads will start their task if the boolean value of them each is false. After the task is done they will make the vars to true so the main processor is able to tick again.
So I want something without a return. I mean as the value is changed inside the method the main could see it.
boolean var = true;
var = methodWhichReturnsTheNewValueOfTheVariable();
and inside the called method:
return newBooleanValue;
or
SomeObjectWithBooleanVariableInside var = new SomeObjectWithBooleanVariableInside(true);
methodWhichModifiesTheObject(var);
and inside the called method:
var.setBooleanValue(newBooleanValue);
A Boolean is such an object: it contains a boolean value. But it's intentionally designed as immutable: its wrapped boolean value can't be changed. So you need to create your own, functional object.
The usual way to do this is the following:
public static void main(String[] args) {
boolean myVar = true;
...
...
myVar = myFunction();
}
public static boolean myFunction() {
// the method should do it's calculation and return the value:
return false;
}
Yes - you cannot modify passed-by-value parameter inside a method in Java (for example in C# you would write method(ref param)).
Why can't you return this value using the method:
public boolean method(params...) {...}
Or you can pass in param the reference to caller:
public void method(params..., CallerClass caller) {
//do something
caller.setValue(Boolean.FALSE);
}
Or you can make this variable accessible in caller and calling method scopes - static variable, etc.
Primitive types are passed by value, so you can't change variables coming as parameter in a method.
This makes also easier to understand how a program works, since this kind of behavior is made more evident in an invocation like this:
boolean prime = false;
prime = isPrime(number);
you can see that found variable is reassigned; while you can assume that number will remain unchanged. This helps in code readability.
There is a dirty trick that sometime can be used. Since arrays are objects, you can use an array to wrap a primitive type:
boolean[] prime = { false };
isPrime(number, result);
public void isPrime(int number, boolean[] result) {
result[0] = true;
}
The object reference is passed by value too, but here we change the content of the array, not the array reference.
This works. But, I don't recommend to design your code like this.
Sometimes, knowing this trick can be useful in unit tests though.
when you think that you changed the value of the primitive boolean it only changed the value in the scope of that method. same with Boolean as it is immutable. changing its value actually assigned a new value to it inside the scope of that method.
you should return the new value from that method and then assign it or you could also use a global boolean that is known to all and to change that one.
(and by the way, if you're dealing with concurrency check out AtomicBoolean)