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;
}
Related
We want to achieve that the Boolean are handled like boolean with lombok Getters/Setters when their name starting with an "is"-prefix. Is there a way to do so with lombok?
We always use the "is"-prefix for our member variables in Java (as well in SQL and JavaScript) as a coding convention. With boolean types we are very happy with default lombok behaviour for getters/setters. Now we want to achieve the same generation logic for Booleans as well, but the lombok default is a different between boolean and Boolean.
I tried the following:
#Data
public class BooleanChallenge {
// #Getter #Setter just work fine for boolean
private boolean isSmallBoolean;
// Boolean are handled different
private Boolean isBigBoolean;
#Accessors(fluent = true)
private Boolean isFluentAccessor;
#Accessors(prefix = "is")
private Boolean isWithPrefix;
#Accessors(prefix = "is", fluent = true)
private Boolean isWithPrefixAndFluent;
private void useThoseGetterzAndSetterz() {
this.isSmallBoolean(); // ✔ "is"-prefix for getter
this.setSmallBoolean(true); // ✔ "set"-prefix for setter
this.getIsBigBoolean(); // ❌ "get is"
this.setIsBigBoolean(true); // ❌ "set is"
this.isFluentAccessor(); // ✔
this.isFluentAccessor(true); // ❌ "is"-prefix instead of "get" prefix
this.getWithPrefix(); // ❌ no "is"-prefix
this.setWithPrefix(true); // ✔
this.withPrefixAndFluent(); // ❌
this.withPrefixAndFluent(true); // ❌
}
}
Here is some stuff.
Don't prefix your boolean field.
That is terrible and ridiculous because,
the JavaBean spec states that the getter for a boolean field must be named
isFieldName, which becomes isIsBlammy().
Stop using a terrible practice as your convention.
It seems that terrible is here to stay.
Also, Lombok recognizes terrible and generates correct getter methods
(isBlammy() in the example).
The correct (JavaBean spec compliant) name of the getter for a Boolean
(note the capital 'B') field is getFieldName.
this is intentional and is not a mistake.
Lombok generates compliant getter methods.
Java autoboxes and autounboxes between primatives and non-primatives
(in this case, between boolean and Boolean).
When you have a getter that returns boolean and you assign the return value
to a Boolean variable,
Java automatically generates the correct Boolean value for the assignment.
The only time you need Boolean is when null is a valid value (i.e. can happen).
If fluentAccessor can never be null,
change it to be boolean an autoboxing will solve your issue.
When null is a legit possible value,
Boolean is appropriate and boolean is not an option.
Additional stuff
Since changing the terrible naming convention is not an option,
you must create the getter yourself.
Here is an example:
// Disable the Lombok getIsHooty method creation.
#Getter(AccessLevel.NONE)
private Boolean isHooty;
public Boolean isHooty()
{
return isHooty;
}
Here are my 50 cents: boolean is binary/dual-state, whereas Boolean is ternary/tri-state, as it takes true, false and null, or to be more precise, Boolean.TRUE, Boolean.FALSE, any self-created object, and null.
When one has a function isSomething you expect it to return either true or false, not null. So a possible null value might screw something up big-time.
That being said, I cannot really help you with your actual problem. What I can suggest is that you enhance the Lombok library so that it creates functions that convert the Boolean return values into booleans, with some default annotation for default-if-null and default false-if-null behavior. But this approach with the 'hidden conversion' already looks quite hackish. A bit much just to keep up coding conventions.
I have a class like so:
public class Achievements(){
boolean score100_Earned_Offline;
boolean score1000_Earned_Offline;
final String score100 = "xxxxxxxxxx" //where xxxxxxxxxx would be replaced with the achievement's Google Play Games ID
final String score1000 = "xxxxxxxxxx" //where xxxxxxxxxx would be replaced with the achievement's Google Play Games ID
}
In my Game class, I check the state of the achievements every tick and act on them as necessary like so (assume all methods to be valid and defined - this is cut down to provide the code necessary to the question).......
public class Game(){
public void checkAchievements(Achievements achievements){
if (score>=100){
unlockAchievement(achievements.score100, achievements.score100_Earned_Offline);
}
if (score>1000){
unlockAchievement(achievements.score100, achievements.score1000_Earned_Offline);
}
}
public void unlockAchievement(String achievementToUnlock, boolean thisAchievementOfflineFlag){
//If user is signed in, then we are ready to go, so go ahead and unlock the relevant achievement....
if (checkSignedIn()){
Games.Achievements.unlock(getApiClient(), achievementToUnlock);
//Otherwise, I want to do is set the relevant flag to true so it can be checked when the user does eventually log in
else{
thisAchievementOfflineFlag=true;
}
}
}
Pass by value
In the 'unlockAchievement' method, the boolean 'thisAchievementOfflineFlag' does get set to true if the user is not logged in, however, it doesn't effect the actual boolean that was originally sent into the method (which as you can see is defined in my 'Achievements' class). I'm guessing this is because Java is Pass by Value and is therefore, creating a local copy of the variable which is valid inside the method only. I did try using Boolean too (wrapper class) but got the same results.
Other ways to achieve this?
I've currently got it set up so I can define each achievement as an enum so each one will have it's own copy of the boolean flag. However, I'm aware that it's not recommended to use enums in Android so if there is a better way that I am missing, I would rather avoid them.
Please note that I don't want to use if checks or switch statements as this is taking place in a game-loop.
Any suggestions appreciated
This is all because Java's implementation of Boolean (also, for example String) is immutable for safety reasons. You can see it here: http://www.explain-java.com/is-string-mutable-in-java-why-wrapper-classes-immutable-in-java/
You can solve your problem by introducing an object wrapper for that boolean:
public class BooleanWrapper {
private boolean value;
public void set(boolean value) {
this.value = value;
}
public boolean get() {
return value;
}
}
Now, this object reference will be passed by value but will still point to the same BooleanWrapper object on the heap. You can simply use getters and setters to change the inner boolean value.
Then your code would become:
public void unlockAchievement(String achievementToUnlock, BooleanWrapper thisAchievementOfflineFlag){
if (checkSignedIn()){
Games.Achievements.unlock(getApiClient(), achievementToUnlock);
else {
thisAchievementOfflineFlag.set(true);
}
}
Java is pass-by-value:
When you pass boolean then you for sure passed it by value, while it is a primitive type. When you pass Boolean, you would think it's an object and that you can change it's state, but actually you cannot because Boolean is implemented as an immutable object (as already said). You can confirm this just by reading the code of java.lang.Boolean.
But if you create your own wrapper class, and in a sense, you control whether you implement it in immutable or mutable way. BooleanWrapper I wrote lets you change the state of that object. And when you pass an object such as this one to the method, it's passed by value. That means that another reference is created, but it points to the same object on heap (see image below).
You could use an AtomicBoolean, which will have pass-by-reference semantics.
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.
It looks like everyone says that right getter for:
primitive boolean -> getter is
object Boolean -> getter get
Example:
public class Test {
private boolean primitive;
private Boolean object;
public boolean isPrimitive() {
return primitive;
}
public Boolean getObject() {
return object;
}
//..
}
Question:
Is there any spec or document that states this is correct and this is the way to specify getters for boolean values? Or this is only a common assumption?
I'm asking becouse for example wsimport generates getter is for Boolean object. Is this a tool bug, or this is allowed and correct?
In the other hand some framweorks don't work properly with such getters. For example JSF (EL) or Dozer.
The getter method for the field boolean myField is getMyfield() or isMyField() (it's up to the user to choose). I personally use the second format, as many source code generating tools do.
This format is a standard, it is defined in the JavaBeans specification. See the section 8.3.2 of this documentation:
http://download.oracle.com/otndocs/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/
Quote from the docs:
In addition, for boolean properties, we allow a getter method to match the pattern:
public boolean is<PropertyName>();
The documentation doesn't talk about the primitive wrappers like the Boolean class.
// "is" used because the value can be either true or false. It's like asking isTrue?
public boolean isPrimitive() {
return primitive;
}
// "get" is used because the value returned can be either true, false or null.
// So, the third state 'null' makes you wonder if 'is' should be used or 'get'.
// "get" is more appropriate as Boolean can also have null.
public Boolean getObject() {
return object;
}
But frankly, it's left to the developer. There's nothing "wrong" in using getBoolean() on a boolean value (is makes more sense, that's it).
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)