Why does this code can cause a NPE? Findbugs give me the hint, that this can occur and it does sometimes :-)
Any ideas?
public Integer whyAnNPE() {
return 1 == 2 ? 1 : 1 == 2 ? 1 : null;
}
EDIT: The code in the question wasn't present when I wrote this answer.
Here's another method to make it slightly clearer:
public static Integer maybeCrash(boolean crash) {
return true ? (crash ? null : 1) : 0;
}
The important point is that we have two conditional expressions here. The inner one is of type Integer due to the last bullet point in the determination of the type as specified in section 15.25.
At that point, we've got a situation like this:
public static Integer maybeCrash(boolean crash) {
Integer tmp = null;
return true ? tmp : 0;
}
Now for the remaining conditional expression, the previous bullet point applies, and binary numeric promotion is performed. This in turn invokes unboxing as the first step - which fails.
In other words, a conditional like this:
condition ? null-type : int
involves potentially boxing the int to an Integer, but a conditional like this:
condition ? Integer : int
involves potentially unboxing the Integer to int.
Original answer
Here's a rather simpler example which is actually valid Java:
public class Test {
public static void main(String[] args) {
int x = args.length == 0 ? 1 : null;
}
}
This is effectively:
int tmp;
if (args.length == 0) {
tmp = 1;
} else {
Integer boxed = null;
tmp = boxed.intValue();
}
Obviously the unboxing step here will go bang. Basically it's because of the implicit conversion of a null expression to Integer, and from Integer to int via unboxing.
Related
This is a simple question:
Is it possible to have an enum with a variable value ?
To be clear i would like to create an enum corresponding to an error code returned by a function which is two bytes, so i would like to do something like
public enum ErrorCode {
ERR_NONE ((byte)0x9000), // No error
ERR_PARAM ((byte)0x8200), // Parameter error
ERR_DATA ((byte)0x83XX), // XX could be any value
}
how to return ERR_DATA for all values beginning by 0x83 ?
Is it possible ?
Thanks
Here's an implementation following Dawood ibn Kareem's suggestion in comments above.
Some points:
This implementation throws an exception if a code matches two enum values. You would need to decide whether you wanted that behaviour, or just return the first match. In that case the ordering of the enum values becomes significant.
You can add new constructors for common cases, e.g. I have one for a value which matches a single code. You could add one for a value which matches a range of codes.
You might also want to throw an exception if no ErrorCode matches the integer code. This implementation returns null in that case, so you'll get an NPE if the caller doesn't check for null, but you won't know what value triggered it.
import java.util.function.Predicate;
public enum ErrorCode {
ERR_NONE (0x9000), // No error
ERR_PARAM (0x8200), // Parameter error
ERR_DATA (n -> (n >= 0x8300 && n <= 0x83FF)), // 0x83XX
ERR_ANOTHER_83 (0x8377);
private final Predicate<Integer> forValue;
ErrorCode(Predicate<Integer> matches) {
this.forValue = matches;
}
ErrorCode(int singleValue) {
this(n -> n == singleValue);
}
public static ErrorCode forInt(int code) {
ErrorCode matchingCode = null;
for (ErrorCode c : ErrorCode.values()) {
if (c.forValue.test(code)) {
if (matchingCode != null) {
throw new RuntimeException("ErrorCodes " + matchingCode.name()
+ " and " + c.name() + " both match 0x"
+ Integer.toHexString(code));
} else {
matchingCode = c;
}
}
}
return matchingCode;
}
public static void main(String[] args) {
System.out.println(ErrorCode.forInt(0x8312));
System.out.println(ErrorCode.forInt(0x9000));
System.out.println(ErrorCode.forInt(0x8377));
}
}
Write a method which, given 0x83NN as input, returns ERR_DATA. Done.
ErrorCode errorCode(int n) {
if (n == 0x9000)
return ERR_NONE;
else if (n == 0x8200)
return ERR_PARAM;
else if (n >= 0x8300 && n <= 0x83ff)
return ERR_DATA;
else
throw new IllegalArgumentException();
}
You have to write code to look up the value in any case. There's no intrinsic 'associate this integer value with this enum constant, and provide a lookup for enum constant given an integer value'.
Note that, for this, there's no need to store the numeric value inside each member of the enum. And also note that your constructor calls like ERR_NONE(0x9000) are not valid unless you've defined a suitable constructor. And if you do define a suitable constructor, you'll need to decide on a single value for the argument of ERR_DATA.
I believe it cannot be the case. According to Oracle Doc,
An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it.
I am new to programming and have a simple question: is there a "better" or more efficient way of doing this...
if (x != 0) {
y = x;
}
or
if (getMethod() != null) {
value = getMethod();
}
I'm new to programming and above code (esp the 2nd one) seems inefficient.
Thanks in advance.
You second example can suffer from a "Time of check, to time of use" weakness. If the first invocation of getMethod() returns non-null, it is possible that your second invocation will return null. A better way to do it would be:
value = getMethod();
if(NULL != value)
{
/* use value as planned */
}
else
{
/* handle a null value, probably an error */
}
if interested, you can read more about TOCTTOU weaknesses here.
For your first example, I don't really see a better way of doing this.
N.B. This answer is from the perspective of a C programmer (seeing as how C was one of your tags).
Hope this helps
- T.
You can make it shorter
if ( x ) y = x;
is the same as
if (x != 0) {
y = x;
}
And
if ( getMethod() ) value = getMethod();
is the same as
if (getMethod() != null) {
value = getMethod();
}
First code snippet:
In C any non-zero value is treated as true and 0 treated as false. So, for the first example, you can rewrite it as:
if (x) {
y = x; // this line will be executed if x not equal to zero
}
Second code snippet:
You called getMethod() twice which is not efficient. As per your code, you are assigning the return value of getMethod() into value if getMethod() returns anything but NULL. So you can use a temporary variable to check the return value of getMethod(), like following:
temp = getMethod();
if (temp != null) {
value = temp;
}
That will reduce calling same method twice.
My code gives me this error:
error: incomparable types: double and .
I have no clue why.
This is what I want to do:
I have a formule (who gives me a double) but if this formule gives me no answer (divide by zero, ... ) I want to print : No answer!
beta & alfa are 2 doubles, you can choose.
double valueOne = valueOne(alfa,beta);
double valueTwo = valueTwo(alfa,beta);
public double valueOne(double alfa, double beta)
{
return (-(Math.sqrt((-beta)/alfa)))+alfa;
}
public double valueTwo(double alfa, double beta)
{
return (Math.sqrt((-beta)/alfa))+alfa;
}
if(valueOne == null && valueTwo == null)
{
System.out.println("No values");
}
Comparing a double to a null is of course illegal because the first one is a value type and value types are never null for which the null stands when comparing to reference types. This page might help you to distinguish the two: What’s the difference between a primitive type and a class type in Java?
If you don't want to throw exceptions on invalid values or results your method could make use of the Double.NaN constnt field:
public double valueOne(double alfa, double beta)
{
// At least one of the values is invalid.
if (Double.isNaN((alfa) || Double.isNaN((beta))
{
return Double.NaN;
}
// Check the alpha or otherwise a div/0 exception may be thrown.
if (alfa == 0.0)
{
return Double.NaN;
}
double divResult = (-beta)/alfa;
// Check the div result because Math.sqrt accepts only positive values:
// If the argument is NaN or less than zero, the result is NaN.
if (divResult < 0.0)
{
return Double.NaN;
}
return (-(Math.sqrt(divResult)))+alfa;
}
double resultValueOne = valueOne(alfa, beta);
if(Double.isNaN((resultOne))
{
System.out.println("No resultValueOne");
}
Sample at ideone
I think you've misunderstood a few things here.
you don't seem to be calling your two methods - I assume you mean something like valueOne(1, 2)
If your calculation gets an error (such as divide by zero) it doesn't return null, it throws an ArithmeticException
Therefore you shouldn't be comparing to null you should use a try catch block to handle errors
you can't compare an atomic type like double to null; only references to objects can be compared to null
you can use string manipulation since java does not allow a primitive type to have null values.
if the string is empty , no values will appear. i hope this helps.
public static void main(String []args){
if(valueOne(0,0).equals("") && valueTwo(0,0).equals(""))
System.out.println("No values");
else
System.out.println("val1:"+valueOne(0,0)+"val2:"+valueTwo(0,0));
}
public static String valueOne(double alfa, double beta){
return ""+(-(Math.sqrt((-beta)/alfa)))+alfa;;
}
public static String valueTwo(double alfa, double beta){
return ""+(-(Math.sqrt((-beta)/alfa)))+alfa;;
}
I guess you need something like this:
public double[] myMethod(double vAlfa, double vBeta, double wAlfa, double wBeta) {
double[] answers = new double[2];
try {
answers[0] = (-(Math.sqrt((-vBeta) / vAlfa))) + vAlfa;
answers[1] = (Math.sqrt((-wBeta)/wAlfa)) + wAlfa;
} catch (Exception e) {
System.out.println("No values");
}
return answers;
}
This method returns the result of processes as an array of doubles (because you have two values).
In the try block, we try to calculate the answers and put them in the array.
and in the catch block, we deal with every exceptions (NullPointerException or DivisionByZero or ...) by an call to System.println(); to print the given string for us.
Hope it helps.
First of all both valueOne and valueTwo are methods but you try to refer to them as variables (?!):
if(valueOne == null && valueTwo == null){
Second, anyway the return type of these methods and (if you define variables of the same type) is double that is a primitive and cannot be null. null is a special value that can be used with object references only.
Take some java tutorial that explains java types for the beginning.
This question already has answers here:
Best way to format multiple 'or' conditions in an if statement
(8 answers)
Closed 1 year ago.
Basically, what I want to do is check two integers against a given value, therefore, classically what you would do is something like this:
//just to get some values to check
int a, b;
a = (int)(Math.random()*5);
b = (int)(Math.random()*5);
//the actual thing in question
if(a == 0 || b == 0)
{
//Then do something
}
But is there a more concise format to do this? Possibly similar to this (which returns a bad operand type):
//just to get some values to check
int a, b;
a = (int)(Math.random()*5);
b = (int)(Math.random()*5);
//the actual thing in question
if((a||b) == 0)
{
//Then do something
}
You can do the following in plain java
Arrays.asList(a, b, c, d).contains(x);
Unfortunately there is no such construct in Java.
It this kind of comparison is frequent in your code, you can implement a small function that will perform the check for you:
public boolean oneOfEquals(int a, int b, int expected) {
return (a == expected) || (b == expected);
}
Then you could use it like this:
if(oneOfEquals(a, b, 0)) {
// ...
}
If you don't want to restrict yourselft to integers, you can make the above function generic:
public <T> boolean oneOfEquals(T a, T b, T expected) {
return a.equals(expected) || b.equals(expected);
}
Note that in this case Java runtime will perform automatic boxing and unboxing for primitive types (like int), which is a performance loss.
As referenced from this answer:
In Java 8+, you might use a Stream and anyMatch. Something like
if (Stream.of(b, c, d).anyMatch(x -> x.equals(a))) {
// ... do something ...
}
Note that this has the chance of running slower than the other if checks, due to the overhead of wrapping these elements into a stream to begin with.
I think that a bit-wise OR:
if ((a | b) == 0) . . .
would work if you want to check specifically for 0. I'm not sure if this saves any execution time. More to the point, it makes for cryptic code, which will make the future maintainer of this code curse you (even if its yourself). I recommend sticking with the more-typing option.
Bah. I misread OP's original logic.
Another go...
If you want to test whether any one of many variables is equal to an expected value, a generic function might work:
public <T> boolean exists(T target, T... values) {
for (T value : values) {
if (target == null) {
if (value == null) {
return true;
}
} else if (target.equals(value)) {
return true;
}
}
return false;
}
This will work for any number of objects of one type. Primitives will be autoboxed so it will work with them as well. Your original code will be something like:
if (test(0, a, b)) {
// do something
}
(A better method name would be desperately needed to even consider whether this an improvement over what you have now. Even if the test expands to 3 or 4 variables, I question the need for this kind of thing.) Note that this also works with arrays:
int[] values = { . . . };
if (test(0, values)) { . . .
and it can be used to test whether an array (or any of a collection of variables) is null.
if(a == 0 || b == 0)
{
//Then do something
}
Why not keep it readable? What is not concise about this? On the other hand,
a = (int)(Math.random()*5);
involves an unnecessary cast. Why not just use Random and invoke nextInt()?
For this example, you can do
if (a * b == 0)
or for more variables
if (a * b * c * d == 0)
while more concise it may not be as clear. For larger values, you need to cast to a long to avoid an overflow.
You could put the integers in a set and see if it contains the given value. Using Guava:
if(newHashSet(a, b).contains(0)){
// do something
}
But two simple int comparisons are probably easier to understand in this case.
Here's a modification of #buc's answer that can take any number of any arguments:
public <T> boolean oneOfEquals(T expected, T... os) {
for (T o : os) {
if (expected.equals(o)) return true;
}
return false;
}
Even if you have used the bit-wise operation as Ted suggested, the expressions are not equal, since one requires at least one of the variables to be zero and the second requires both of them to be zero.
Regarding your question, there is no such shortcut in Java.
You can try this code:
public static boolean match (Object ref, Object... objects)
{
if (ref == null)
return false;
//
for (Object obj : objects)
if (obj.equals (ref))
return true;
//
return false;
} // match
So if you can check this way:
if (match (reference, "123", "124", "125"))
; // do something
In Java 8 we can achieve the same by using the below method:
private boolean methodName(int variant,int... args){
if(args.length > 0){ return Arrays.stream(args).anyMatch( x -> x == variant); }
return false;
}
The given method will return true if the variant will match any possible input(s). This is used for or condition.
In the same way, if you want to do &&(and) condition then you just need to used other Java 8 methods:
Note: These methods take Predicate as an argument.
anyMatch: return true the moment the first predicate returns true otherwise false.
allMatch: return true if all the predicates return true otherwise false.
noneMatch: return true if none of the predicates return true otherwise false.
Performance Note: This is good when you have enough amount of data to
check as it has some overhead but it works really well when you use
this for enough amount of data. normal way is good for just two
conditions.
There is no special syntax for that. You could make a function for that. Assuming at least Java 1.5:
public <T> boolean eitherOneEquals(T o1, T o2, T expectedValue) {
return o1.equals(expectedValue) || o2.equals(expectedValue);
}
if(eitherOneEquals(o1, o2, expectedValue)) {
// do something...
}
public int getFreezeColumns() {
Integer currentValue = (Integer) checkValueBinding("freezeColumns", this.freezeColumns);
if (currentValue != null) {
return currentValue;
}
return 0;
}
FindBugs says :
A primitive is boxed, and then immediately unboxed. This probably is due to a manual boxing in a place where an unboxed value is required, thus forcing the compiler to immediately undo the work of the boxing.
How can I possibly fix this ?
I think the complaint is somewhat misleading: you are not boxing the return value of checkValueBinding which is an Object, but you are casting it to Integer prematurely
Try changing the code to see if it helps you avoid the warning:
public int getFreezeColumns() {
Object currentValue = checkValueBinding("freezeColumns", this.freezeColumns);
if (currentValue != null) {
return (Integer)currentValue;
}
return 0;
}
Seems to me like it's complaining that you are creating an Integer, and then converting it to int right away to return it.
What does checkValueBinding return? Do you really need to wrap it into an Integer?