I have the following class:
public class NewGameContract {
public boolean HomeNewGame = false;
public boolean AwayNewGame = false;
public boolean GameContract(){
if (HomeNewGame && AwayNewGame){
return true;
} else {
return false;
}
}
}
When I try to use it like so:
if (networkConnection){
connect4GameModel.newGameContract.HomeNewGame = true;
boolean status = connect4GameModel.newGameContract.GameContract();
switch (status){
case true:
break;
case false:
break;
}
return;
}
I am getting the error:
incompatible types found: boolean required: int on the following
`switch (status)` code.
What am I doing wrong?
You can't switch on a boolean (which only have 2 values anyway):
The Java Language Specification clearly specifies what type of expression can be switch-ed on.
JLS 14.11 The switch statement
SwitchStatement:
switch ( Expression ) SwitchBlock
The type of the Expression must be char, byte, short, int, Character, Byte, Short, Integer, or an enum type, or a compile-time error occurs.
It is a lot more readable and concise to simply use an if statement to distinguish the two cases of boolean.
you don't want to switch on a boolean, just use a simple if/else
if (status) {
....
} else {
....
}
edit : switch is only used for ints, chars, or enums (i think that's all, maybe there are others?)
edit edit : it seems short and byte are also valid types for switching, as well as the boxed versions of all of these (Integer, Short, etc etc)
Switch statements in Java can use byte, short, char, and int (note: not long) primitive data types or their corresponding wrapper types. Starting with J2SE 5.0, it became possible to use enum types. Starting with Java SE 7, it became possible to use Strings.
Can't use boolean in switch, only int. Please read the Java docs for the switch statement.
Switch takes an integer value, and a boolean cannot be converted to an integer.
In java, a boolean is a type in its own right, and not implicitly convertible to any other type (except Boolean).
In Java, switch only works for byte, short, char, int and enum. For booleans you should use if/else as there are a very limited number of states.
Related
How do if statements recognize the Boolean object as a boolean? such as:
Boolean b = new Boolean(true);
if(b){
System.out.println("true!");
} else {
System.out.println("false!");
}
This would print true, but how is Boolean recognized?
It is called autoboxing and works for primitive types in Java, look here for a brief SO explanation or here for the official documentation. Java automatically converts the object representation Boolean into the corresponding primitive type boolean and back. The first is called unboxing and the latter boxing.
Why class cast exception from Double to double?
Used like:
Console.writeLine(Validator.TryParse("1.5", double.class));
Code:
public static <T> T TryParse(Object ConvertFrom, java.lang.Class<T> ConvertTo) {
switch(ConvertTo.getSimpleName().toLowerCase()) {
case "int":
case "integer": return ConvertTo.cast((int)Integer.parseInt((String)ConvertFrom));
case "string": return ConvertTo.cast(String.valueOf(ConvertFrom));
case "double": return ConvertTo.cast((double)Double.parseDouble((String)ConvertFrom));
case "float": return ConvertTo.cast((float)Float.parseFloat((String)ConvertFrom));
case "long": return ConvertTo.cast((long)Long.parseLong((String)ConvertFrom));
default: return null;
}
}
You are mixing primitives and boxed primitives. Calling TryParse("1.5", Double.class) will work fine (and you can remove all the unnecessary primitive casts like (int) (double) etc).
The problem you encounter is that Class#cast first checks Class#isInstance and:
Double.class.isInstance(1.0);
is true but:
double.class.isInstance(Double.valueOf(1.0))
double.class.isInstance(1.0d)
are false as explained in the javadoc
If this Class object represents a primitive type, this method returns false.
Bottom line: primitive.class.cast() will always throw an exception.
If you still need to define the class each time you call the validator, why don't you just use the valueOf method of each class? The Object classes such as Integer and Double will be able to handle the primitives and return objects...
As it's been asked before, are you sure you need to implement this? You might want to review your design.
It should be as below, Note the Caps in Double.
Console.writeLine(Validator.TryParse("1.5", Double.class));
You can use Double.doubleValue() and Integer.intValue().
More reading:
Double.doubleValue()
Integer.intValue()
Except....
Your method wants to return an Object, so you can't return primitives.
Editorial:
It seems like you're trying to do something that is very unnatural and un-Java (Java is a typed language for a reason).
I need some classes implements Comparator, and for one I want to compare primitive boolean (not Boolean) values.
IF it was a Boolean, I would just return boolA.compareTo(boolB); which would return 0, -1 or 1. But how can I do this with primitives?
You can look up how it is implemented for the java.lang.Boolean, since that class, naturally, uses a primitive boolean as well:
public int compareTo(Boolean b) {
return (b.value == value ? 0 : (value ? 1 : -1));
}
As of Java 7 you can simply use the built-in static method Boolean.compare(a, b).
Since Java 7, the logic that Marko Topolnik showed in his answer has moved into another method to expose a way to compare primitive boolean.
Javadoc for Boolean.compare(boolean x, boolean y):
public static int compare(boolean x, boolean y)
Compares two boolean values. The value returned is identical to
what would be returned by:
Boolean.valueOf(x).compareTo(Boolean.valueOf(y))
An even better approach and correct use of Boolean-Adapter class
public int compare(boolean lhs, boolean rhs) {
return Boolean.compare(lhs, rhs);
}
EDIT:
Hint: This sorts the "false" values first. If you want to invert the sorting use:
(-1 * Boolean.compare(lhs, rhs))
You can use java's autoboxing feature to alleviate this problem. You can read about autoboxing here: Java autoboxing
You can compare two primitive boolean values b1 and b2 in following way.
(Boolean.valueOf(b1).equals(Boolean.valueOf(b2))
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
While using Java's switch case, it excepts only char and int, but I want to provide string cases. How to make this possible?
You cannot have strings in a switch-case (yet). It's on its way in Java 7.
The current types that it accepts include char, byte, short, int, Character, Byte, Short, Integer, or an enum type.
From the Java Language Specification:
The type of the Expression must be char, byte, short, int, Character, Byte, Short, Integer, or an enum type (§8.9), or a compile-time error occurs.
...
All of the following must be true, or a compile-time error will result:
Every case constant expression associated with a switch statement must be assignable (§5.2) to the type of the switch Expression.
No switch label is null.
No two of the case constant expressions associated with a switch statement may have the same value.
At most one default label may be associated with the same switch statement.
As other replies have stated, Java (currently) does not support switching on String values. There are three commonly used approaches for achieving the same effect:
Replace the switch with a chain of if ... else if ... statements. (Yuck).
Create and populate a HashMap that maps the strings to integer codes and then switch on the codes.
Define an enum type whose values have names that are the same as the Strings, use EType.valueOf(String) to map the strings to enum values, and switch on the enum values. (It may be more complicated if you are required to obey the Java identifier style rules for the enum values, or if the strings contain non-identifier characters.)
#Pete Kirkham adds the "classic hack" of switching on the hashcode of the String. However, there are a couple of problems with that:
It doesn't correctly deal with the case where the supplied string is not one of the required strings. (Think: many strings hash to the same hashcode.)
The hashcodes will most likely be widely spaced, so the JIT compiler will have to compile the switch as a sequence of test / branches based on the hashcode values. That is faster than test / branches based on String.equals(), but it is O(N) ... versus O(1) for a switch that compiles to a jump table.
What can I switch on?
As of Java 6, you can only switch on the following types:
JLS 14.11 The switch statement
SwitchStatement:
switch ( Expression ) SwitchBlock
The type of the Expression must be char, byte, short, int, Character, Byte, Short, Integer, or an enum type, or a compile-time error occurs. [...] Every case constant expression associated with a switch statement must be assignable to the type of the switch Expression.
So what can I do?
Depending on your use case, you may be able to use enum instead of String. Unlike String, you can switch on an enum. Here's an example:
public class EnumSwitchSample {
static enum Color {
BLACK, WHITE;
}
public static void main(String[] args) {
test(Color.valueOf("BLACK"));
// "It's black!"
test(Color.WHITE);
// "It's white!"
}
static void test(Color c) {
switch (c) {
case BLACK:
System.out.println("It's black!");
break;
case WHITE:
System.out.println("It's white!");
break;
}
}
}
However, enum in Java is actually quite powerful, and you may not even need to switch on it. Here's an example:
public class EnumMemberExample {
static enum Mood {
SCREAM("I'M LOUD AND OBNOXIOUS!!!") {
#Override public String say(String statement) {
return statement.toUpperCase().replaceAll("!", "!!!");
}
},
WHISPER("Ssh... Be vewy vewy quiet...") {
#Override public String say(String statement) {
return statement.toLowerCase().replaceAll("!", "...");
}
};
final String msg;
Mood(String msg) { this.msg = msg; }
String getMessage() { return msg; }
abstract String say(String statement);
}
public static void main(String[] args) {
test(Mood.SCREAM);
// "I'M LOUD AND OBNOXIOUS!!!"
// "HELLO!!! HOW ARE YOU!!!"
test(Mood.WHISPER);
// "Ssh... Be vewy vewy quiet..."
// "hello... how are you..."
}
static void test(Mood m) {
System.out.println(m.getMessage());
System.out.println(m.say("Hello! How are you!"));
}
}
See also
java.util.Enum
Java Language Guide/Enums
Related questions
Switch Statement With Strings in Java?
Optimizing if-else /switch-case with string options
using switch in strings
Switching on a string/implementing button actions
switch-case is a language construct that is designed to accept only integral values. You cannot change the way it works.
I you're really desperate you could switch on the String's digest. If you're into that sort of thing that is.
import java.util.zip.Adler32;
public class StringSwitch {
public static void main(String[] args) {
String arg;
if (args == null || args.length == 0) {
arg = "stackoverflow";
} else {
arg = args[0];
}
Adler32 algorithm = new Adler32();
algorithm.update(arg.getBytes());
int hash = (int) algorithm.getValue();
switch (hash) {
case 647693707:
System.out.println("Programming Q & A");
break;
case 145556093:
System.out.println("Narwhals and bacon");
break;
case 193790704:
System.out.println("How do they work?");
break;
}
}
}
Let me put my dogmatic hat on (and you're coding in Java so I'm assuming you care about OOP)
Rather than asking: how do I do the wrong thing? instead ask: what is the right thing to do? In this case: http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html
and for some discussion: http://www.c2.com/cgi/wiki?ReplaceConditionalWithPolymorphism