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).
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 method that parses a String and converts it to a boolean.
The legal values are "true" and "false".
boolean convertStringToBoolean(String text) {
if (text.equals("true") {
return true;
} else if (text.equals("false")) {
return false;
} else {
throw new IllegalArgumentException(text);
}
}
When I use this variable, I get a naming problem.
void doSomething(String isSpecificReadString) {
boolean isSpecificRead = convertStringToBoolean(isSpecificReadString);
...
}
The problem is that the parameter carries a meaning that I want to keep in its name.
The meaning doesn't change just because the type is changed.
So far, my solution has been to just suffix the type to the parameter.
But I don't like this solution.
What should I call the variables to solve this problem?
So far, my solution has been to just suffix the type to the parameter.
But I don't like this solution.
Strongly typed language as Java works in this way.
Variables cannot change their type at runtime.
You have to accept the language constraints.
Converted a data from a type into another type within a method may create this issue.
But your actual solution is rather fine.
The intention is clear and you kept a natural name for the target variable.
You indeed added the type suffix only for the input that will be converted (temporary/intermediary variable), not for the output that will be used in the next statement(s).
As inspired by Andy Turner, I can make two doSomething methods.
A method that takes a String and another that takes a boolean.
The String method can then call the boolean method.
As follows:
void doSomething(String isSpecificRead) {
doSomething(convertStringToBoolean(isSpecificReadString));
}
void doSomething(boolean isSpecificRead) {
...
}
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;
}
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.
In C# I can a variable to allow nulls with the question mark. I want to have a true/false/null result. I want to have it set to null by default. The boolean will be set to true/false by a test result, but sometimes the test is not run and a boolean is default to false in java, so 3rd option to test against would be nice.
c# example:
bool? bPassed = null;
Does java have anything similar to this?
No.
Instead, you can use the boxed Boolean class (which is an ordinary class rather a primitive type), or a three-valued enum.
you can use :
Boolean b = null;
that is, the java.lang.Boolean object in Java.
And then also set true or false by a simple assignment:
Boolean b = true;
or
Boolean b = false;
No, in java primitives cannot have null value, if you want this feature, you might want to use Boolean instead.
Sure you can go with Boolean, but to make it more obvious that your type can have "value" or "no value", it's very easy to make a wrapper class that does more or less what ? types do in C#:
public class Nullable<T> {
private T value;
public Nullable() { value = null; }
public Nullable(T init) { value = init; }
public void set(T v) { value = v; }
public boolean hasValue() { return value != null; }
public T value() { return value; }
public T valueOrDefault(T defaultValue) { return value == null ? defaultValue : value; }
}
Then you can use it like this:
private Nullable<Integer> myInt = new Nullable<>();
...
myInt.set(5);
...
if (myInt.hasValue())
....
int foo = myInt.valueOrDefault(10);
Note that something like this is standard since Java8: the Optional class.
https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
Yes you can.
To do this sort of thing, java has a wrapper class for every primitive type. If you make your variable an instance of the wrapper class, it can be assigned null just like any normal variable.
Instead of:
boolean myval;
... you can use:
Boolean myval = null;
You can assign it like this:
myval = new Boolean(true);
... And get its primitive value out like this:
if (myval.booleanValue() == false) {
// ...
}
Every primitive type (int, boolean, float, ...) has a corresponding wrapper type (Integer, Boolean, Float, ...).
Java's autoboxing feature allows the compiler to sometimes automatically coerce the wrapper type into its primitive value and vice versa. But, you can always do it manually if the compiler can't figure it out.
In Java, primitive types can't be null. However, you could use Boolean and friends.
No but you may use Boolean class instead of primitive boolean type to put null
If you are using object, it allows null
If you are using Primitive Data Types, it does not allow null
That the reason Java has Wrapper Class