I have a utility function which convert parseDouble value to string.
public static BigDecimal setValue(Object o) {
BigDecimal value = new BigDecimal(0);
if(o!= Null){
value=BigDecimal.valueOf(Double.parseDouble(o.toString()));
}
return value;
}
I have tried with (o!=null && !isEmpty(o)) and (o!="" && o!=null) but it is still throwing same error.
Transaction amount which is processing this utility function contains empty value.
Firstly I don't understand why you are taking object type as an input, however to resolve your issue you can do something like this. But I would strongly advice you to change the method signature it is misleading.
public static BigDecimal setValue(Object o) {
var value = new BigDecimal(0);
if (o != null) {
if(o instanceof String) {
if (((String) o).trim().length()>0) {
value = new BigDecimal((String) o);
}
}
}
return value;
}
I would change the method signature to BigDecimal setValue(String s). Your null check and length check code should then work fine.
Also the method name is misleading. The method does not set anything. Something like convertToBigDecimal would be clearer.
Related
I have a class as below, before I set the data I need to check whether getValue() is present and it's value is empty.
public class Money {
{
private String value;
private String currency;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getCurrency() {
return currency;
public void setCurrency(String currency) {
this.currency = currency;
}
}
//JSON is like this
"money": {
"currency": "USD",
"value": ""
}
I want to check whether this getValue() is present or not like obj.getMoney().getValue() != null,
and then I need to check it's value is empty... obj.getMoney().getValue().equals("") but it fails on this condition obj.getMoney().getValue() != null as null.
If the following check fails
if (obj.getMoney().getValue() != null) { ... }
then it implies that the money object itself is null. In this case, you can slightly modify your if condition to check for this:
if (obj.getMoney() != null && obj.getMoney().getValue() != null) { ... }
You said that first you need to check whether value is null or not and then also check whether the value is empty or not,
You can do the following
if (obj.getMoney() != null && obj.getMoney().getValue() != null && !obj.getMoney().getValue().isEmpty()) {
// rest of the code here
}
obj.getMoney().getValue() will give you null pointer exception. You should check for null object before using . after it. Example code:
Below code looks huge but it's actually readable and it will be optimized by compiler.
if(obj != null){
Money money = obj.getMoney();
if(money != null) {
String value = money.getValue();
//Add you logic here...
}
}
I think you are getting null point exception. You are facing this exception because obj.getMoney() is already null. Since you are trying to get a null object's value, so you are getting this exception. Correct code will be
if ((obj.getMoney() != null) && (obj.getMoney().getValue().trim().length() > 0)) {
// Execute your code here
}
When instantiating your obj, gives a new. The form of validation is correct, the problem is in the obj that was not initialized. (I believe)
Please have a look on following Class, I need to check if there is valid value in the variable. All works fine if there is a proper value in variable instead of null, When it comes null the behaviour is not what I expect (Although it might make sense if Integer a = null; when checked as a instanceof Integer,
Can some one guide me how to achieve correct result from following class?
package com.mazhar.hassan;
public class ValueChecker {
public static boolean empty(Integer value) {
System.out.println("Integer");
return (value != null && value.intValue() > 0);
}
public static boolean empty(Long value) {
System.out.println("Long");
return (value != null && value.longValue() > 0);
}
public static boolean empty(String value) {
System.out.println("String");
return (value != null && value.length() > 0);
}
public static boolean empty(Object value) {
System.out.println("Object");
return (value != null);
}
public static void checkAll(Object... args) {
for(Object o: args) {
if (o instanceof Integer) {
empty((Integer)o);
}
else if (o instanceof Long) {
empty((Long)o);
}
else if (o instanceof String) {
empty((String)o);
}
else {
empty(o);
}
}
}
public static void main (String[] args) {
Integer a = null;
Long b = null;
String x = null;
Object y = null;
if (a instanceof Integer) {
System.out.println("a is Integer");
} else {
System.out.println("a is not Integer");
}
System.out.println("/---------------------------------------------------/");
checkAll(a,b,x,y);
System.out.println("/---------------------------------------------------/");
empty(a);
empty(b);
empty(x);
empty(y);
}
}
Why I need exact type checking is, I thave to throw erros like "Not valid Integer", "No valid Long" etc.
The output of above class is as follows.
/-----------------------(Output 1)----------------------------/
a is not Integer
/-----------------------(Output 2)----------------------------/
Object
Object
Object
Object
/------------------------(Output 3)---------------------------/
Integer
Long
String
Object
Output 1: a is not integer (checked by instanceof) can not recognize it but when passed to a overloaded function goes to the right function (Output 3)
Output 2: How to achieve checkAll with multiple/dynamic param checkAll(varInt, varLong, varString, varObject)
The behaviour for Output 1 is caused by the fact that method overloads are bound at compile time. So the specific overload to pick is bound before the program even runs. instanceof, on the other hand, is a runtime check.
Thus, at runtime a instanceof Integer is effectively null instanceof Integer, which is obviously false.
But for each of those individual method calls, the proper method is called because the compiler bound the specific overload of the method at compile time, based on the reference type of the variable. Thus:
empty(a); // Compiled to a call to empty(Integer value)
empty(b); // Compiled to a call to empty(Long value)
empty(x); // Compiled to a call to empty(String value)
empty(y); // Compiled to a call to empty(Object value)
So regardless of the actual object that a, b, x, and y reference, you'll always get the right output on your console for the respective object.
Output 2: How to achieve checkAll with multiple/dynamic param checkAll(varInt, varLong, varString, varObject)
Well, if you're going to pass null, you can't really. null is null at runtime, and doesn't have any type information associated with it. The JVM can't tell that one null is a "String null" or an "Object null". It's just null. So you can't really implement the multiple check you want to for null inputs -- null instanceof ______ will always return false, so you'll always end up with your default case.
If you pass actual objects, though, that method should work properly.
problem:
Integer a = null;
Long b = null;
String x = null;
Object y = null;
You cant use instanceof on null values, it expect the objects to be instantiated thus giving you wrong result.
solution:
instantaite the object first before you check for instance.
The problem here is that when you check instanceof in your loop, you are checking null. null is not an instance of anything, it is the absence of an instance.
If you want to achieve something like this, you're going to have to change your API for checkAll(Object ...) to something that tells the function what types to expect:
public class ValueChecker {
public static boolean checkAll(Object[] args, Class<?>[] types) {
if (args == null || types == null || args.length != types.length)
throw new RuntimeException("programming error");
for (int i = 0; i < args.length; i++) {
if (types[i] == null)
throw new RuntimeException("programming error");
if (args[i] == null || !types[i].isAssignableFrom(args[i].getClass())) {
System.out.println("arg " + (i +1) + " is not " + types[i].getSimpleName());
return false;
}
}
return true;
}
public static void main(String[] args) {
Integer a = null;
Long b = null;
String x = null;
Object y = null;
checkAll(
new Object[] {a, b, x, y},
new Class<?>[] {Integer.class, Long.class, String.class, Object.class}
);
}
}
Is it possible to wrap following code in a reusable function?
EDIT: this is just an example, I want a working solution for ALL recursion depths
what I want is that following code is generated:
if (MyObject o == null ||
o.getSubObject() == null ||
o..getSubObject().getSubSubObject() == null /*||
... */)
return defaultValue;
return o.getSubObject().getSubObject()/*...*/.getDesiredValue();
by calling something like
Object defaultValue = null;
Object result = NullSafeCall(o.getSubObject().getSubObject()/*...*/.getDesiredValue(), defaultValue);
The seond code block is just an idea, I don't care how it looks like, all I want is that I, if desired, can avoid all the null checks before calling a deeper function...
Injection could do this propably, but is there no other/easier solution? Never looked at injection before yet...
EDIT2: example in another language: http://groovy.codehaus.org/Operators#Operators-SafeNavigationOperator
Not really, any code you would write this way would look horrible and/or use very slow reflection. Unless you use an actual Java preprocessor that can understand and change the code you've written.
A better (but associated with quite a bit of refactoring) approach would be to make sure that the values in question cannot possibly be null. For example, you could modify the individual accessors (getSubObject(), getDesiredValue()) to never return null in the first place: make them return default values. The accessors on the default values return default values in turn.
Java8 helps to get the closest you'll get to your syntax with decent performance I suspect;
// Evaluate with default 5 if anything returns null.
int result = Optional.eval(5, o, x->x.getSubObject(), x->x.getDesiredValue());
This can be done with this utility class;
class Optional {
public static <T, Tdef, T1> Tdef eval(Tdef def, T input, Function<T,T1> fn1,
Function<T1, Tdef> fn2)
{
if(input == null) return def;
T1 res1 = fn1.apply(input);
if(res1 == null) return def;
return fn2.apply(res1);
}
}
Sadly, you'll need a separate eval() defined per number of method calls in the chain, so you may want to define a few, but compile time type safe and reusable with just about any calls/types.
You can do something like this
public static Object NullSafeCall(MyObject o,Object defaultValue){
if ( o == null || o.getSubObject() == null)
{
return defaultValue;
}
else
{
return o.getSubObject().getDesiredValue();
}
}
Now you can call this method as follows
Object result = NullSafeCall(o, defaultValue);
i would suggest just replace
Object result = NullSafeCall(o.getSubObject().getDesiredValue(), defaultValue);
by the
Object result = (o == null || o.subObject == null) ? defaultVlue : o.getSubObject().getDesiredValue();
Create method only if you can reuse it......
What you want is not possible. It is essential to understand that using this syntax: Object result = NullSafeCall(o.getSubObject().getSubObject() ...); the part of o.getSubObject().getSubObject() will be evaluated before any control passes to the function/method thus throwing the exception.
It is required to have some type of context before executing such code. The closest to this I could think of, can be done using anonymous inner classes like the example below:
// intended to be implemented by an anonymous inner class
interface NullSafeOperation<T> {
public T executeSafely();
};
// our executor that executes operations safely
public static class NullSafeExecutor<T> {
public NullSafeExecutor() {}
public T execute(T defaultValue, NullSafeOperation<T> nso) {
T result = defaultValue;
try {
result = nso.executeSafely();
} catch(NullPointerException e) {
// ignore
}
return result;
}
// utility method to create a new instance and execute in one step
public static <T> T executeOperation(T defaultValue, NullSafeOperation<T> nso) {
NullSafeExecutor<T> e = new NullSafeExecutor<T>();
T result = e.execute(defaultValue, nso);
return result;
}
}
public static void main(String[] args) {
final String aNullString = null;
String result = NullSafeExecutor.executeOperation("MyDefault", new NullSafeOperation<String>() {
#Override
public String executeSafely() {
// trying to call a method on a null string
// it will throw NullPointerException but it will be catched by the executor
return aNullString.trim();
}
});
System.out.println("Output = " + result); // prints: Output = MyDefault
}
Is there a BigDecimal library with the basic operations of BigDecimal which allows null values?
Null should be treated as 0 for mathematical purpose.
I don't want to do all the null checks for possible null values.
You either never allow null values in database, application or view and initialize everything with new BigDecimal(0) or perform null checks on every usage for nullable values.
Something like:
public static BigDecimal add(final BigDecimal value, final BigDecimal augend)
{
if (value == null)
return augend;
else if (augend == null)
return value;
else
return value.add(augend);
}
public static BigDecimal multiply(final BigDecimal value, final BigDecimal multiplicand)
{
if (value == null || multiplicand == null)
return null;
return value.multiply(multiplicand);
}
Save the coding, just don't allow null values in the database. Make the default value zero.
As for new BigDecimal(0): no, use BigDecimal.ZERO.
I had a similar problem (not related to a database though, just needed to sum up a couple of nullable BigDecimals). Did not find any library, so had to write the following function myself:
public static BigDecimal add(BigDecimal... addends) {
BigDecimal sum = BigDecimal.ZERO;
if (addends != null) {
for (BigDecimal addend : addends) {
if (addend == null) {
addend = BigDecimal.ZERO;
}
sum = sum.add(addend);
}
}
return sum;
}
The same in Java 8:
public static BigDecimal add(BigDecimal... addends) {
if (addends == null) {
return BigDecimal.ZERO;
}
return Arrays.stream(addends)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
I guess I don't see the point of the library checking for null. Sure, the library won't throw a NPE, but the caller is eventually going to have to check for it. What is the caller of your above multiply going to do? It can't just use the output. It's going to have to check to see if the returned value is null at some point before it can do anything with the value.
Also, for any application I've ever written, a null is much different than zero. I wouldn't want to use one that treated a null as zero.
If your requirement is that nulls aren't allowed in your DB, I would check for nulls in your DAO layer before writing to the DB.
You can have a look on this library: https://github.com/MatWein/SCalc
It can handle every number (BigDecimal, Double, custom types, ...) and handles null values as zero.
If the list contains null elements, it doesn't equals null...
So here is a unit test that test all the cases and its implementation :
#ParameterizedTest
#MethodSource("shouldSumBigDecimalsParams")
void shouldSumBigDecimals(BigDecimal expectedSum, BigDecimal first, BigDecimal second) {
BigDecimal sum = bigDecimalsSum(first, second);
assertThat(sum).isEqualTo(expectedSum);
}
private static Stream<Arguments> shouldSumBigDecimalsParams() {
return Stream.of(
Arguments.of(new BigDecimal("1010"), new BigDecimal("1000"), BigDecimal.TEN),
Arguments.of(new BigDecimal("1000"), new BigDecimal("1000"), null),
Arguments.of(BigDecimal.TEN, null, BigDecimal.TEN),
Arguments.of(BigDecimal.ZERO, null, BigDecimal.ZERO),
Arguments.of(BigDecimal.ZERO, BigDecimal.ZERO, null),
Arguments.of(BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO),
Arguments.of(null, null, null)
);
}
The implementation :
static BigDecimal bigDecimalsSum(BigDecimal... bigdecimals) {
if (bigdecimals == null || Arrays.stream(bigdecimals).allMatch(Objects::isNull)) {
return null;
}
return Arrays.stream(bigdecimals)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
Is it possible to nest more than 5 'Conditional Operators' in Java. I ask because it seems that I cause a compiler exception when I try to compile this code:
public Object getValue() {
return
number != null ? number :
string != null ? string :
bool != null ? bool :
date != null ? date :
list != null ? list :
null;
}
I have narrowed it down to this code because if I comment out the last line it seems to compile fine.
public Object getValue() {
return
number != null ? number :
string != null ? string :
bool != null ? bool :
date != null ? date :
// list != null ? list :
null;
}
Does anybody else know if this is a limitation of the java compiler or am I jumping to false conclusions, it would be great if someone else could try to reproduce this. If anybody is interested I have reproduced and posted the Stack Trace from the compiler here https://gist.github.com/919284.
Note that it is very likely a bug in the compiler not my code, as the output said "Please File a Bug at Java Developer Connect site" (or something similar). I am asking here because I am not sure what that bug report would contain.
EDIT:
Chris L has reproduced this, see his answer
I reproduced your error (using Sun JDK 1.6.0_24 on Mac). I simplified your class a little bit to:
import java.util.ArrayList;
import java.util.Date;
public class Test3 {
private Number number;
private String string;
private Boolean bool; // Replace Boolean with Object, and it compiles!
private Date date;
private ArrayList<String> list; // Replace ArrayList with List, and it
// compiles!
public Object getValue() {
return number != null ? number :
string != null ? string :
bool != null ? bool :
date != null ? date :
list != null ? list :
null;
}
}
My stack trace is basically the same as yours. (It has nothing to do with GWT, by the way.)
An exception has occurred in the compiler (1.6.0_24). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.AssertionError
at com.sun.tools.javac.jvm.Code$State.forceStackTop(Code.java:1688)
at com.sun.tools.javac.jvm.Gen.visitConditional(Gen.java:1679)
at com.sun.tools.javac.tree.JCTree$JCConditional.accept(JCTree.java:1021)
at com.sun.tools.javac.jvm.Gen.genExpr(Gen.java:818)
at com.sun.tools.javac.jvm.Gen.visitConditional(Gen.java:1678)
at com.sun.tools.javac.tree.JCTree$JCConditional.accept(JCTree.java:1021)
at com.sun.tools.javac.jvm.Gen.genExpr(Gen.java:818)
at com.sun.tools.javac.jvm.Gen.visitConditional(Gen.java:1678)
at com.sun.tools.javac.tree.JCTree$JCConditional.accept(JCTree.java:1021)
at com.sun.tools.javac.jvm.Gen.genExpr(Gen.java:818)
at com.sun.tools.javac.jvm.Gen.visitReturn(Gen.java:1626)
at com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1138)
at com.sun.tools.javac.jvm.Gen.genDef(Gen.java:665)
at com.sun.tools.javac.jvm.Gen.genStat(Gen.java:700)
at com.sun.tools.javac.jvm.Gen.genStat(Gen.java:686)
at com.sun.tools.javac.jvm.Gen.genStats(Gen.java:737)
at com.sun.tools.javac.jvm.Gen.visitBlock(Gen.java:1013)
at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:739)
at com.sun.tools.javac.jvm.Gen.genDef(Gen.java:665)
at com.sun.tools.javac.jvm.Gen.genStat(Gen.java:700)
at com.sun.tools.javac.jvm.Gen.genMethod(Gen.java:893)
at com.sun.tools.javac.jvm.Gen.visitMethodDef(Gen.java:866)
at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:639)
at com.sun.tools.javac.jvm.Gen.genDef(Gen.java:665)
at com.sun.tools.javac.jvm.Gen.genClass(Gen.java:2198)
at com.sun.tools.javac.main.JavaCompiler.genCode(JavaCompiler.java:617)
at com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1289)
at com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1259)
at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:765)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:730)
at com.sun.tools.javac.main.Main.compile(Main.java:353)
at com.sun.tools.javac.main.Main.compile(Main.java:279)
at com.sun.tools.javac.main.Main.compile(Main.java:270)
at com.sun.tools.javac.Main.compile(Main.java:69)
at com.sun.tools.javac.Main.main(Main.java:54)
I can only confirm that this compiles without error for me in both eclipse 3.5 and javac 1.6.0_u24:
public class Test {
Object number=null, string=null, bool=null, date=null, list=null;
public Object getValue() {
return
number != null ? number :
string != null ? string :
bool != null ? bool :
date != null ? date :
list != null ? list :
null;
}
}
This compiles fine on ideone:
public static void main (String[] args) throws java.lang.Exception
{
Object number = null;
Object string = null;
Object list = null;
Object bool = null;
Object date = null;
Object o =
number != null ? number :
string != null ? string :
bool != null ? bool :
date != null ? date :
list != null ? list :
null;
}
Double check that list is declared in a way that it is accessible inside the method.
May be a bug in your java compiler. I suggest you update your java to the latest and greatest (if there is one) and reproduce. You can install as many different versions of Java as you like.
I don't think there is a limitation while it is syntactically correct. I would guess the java compiler just will expand its parse tree like for a deep if/else if - nesting.
There is no limit as low as this. A method must compile to less than 64KB of byte code.
I compiled your example fine. Is there any reason you don't have just one field?
EDIT: Added setters to check valid types.
public class Holder implements Serializable {
Serializable value;
public void setValue(Number value) {
this.value = value;
}
public void setValue(String value) {
this.value = value;
}
public void setValue(Boolean value) {
this.value = value;
}
public void setValue(Date value) {
this.value = value;
}
public <L extends List & Serializable> void setValue(L value) {
this.value = value;
}
public Serializable getValue() {
return value;
}
}
I know this is an old post, but my recent experiance might shed some light on the subject for those of you who are interested. It's something to be aware of.
Basically, I "broke" some existing code by implementing Comparable in one of my other classes. Here's a stripped down version that generates the same "An exception has occurred in the compiler..."
If there are fewer than 5 expressions in the nested conditional, or if the USDollars class does not implement Comparable this code compiles.
public class TestHit
{
protected final String fSymbol;
protected final long fTime;
protected final USDollars fBasePrice;
public TestHit(String aSymbol, long aTime, int aBasePrice)
{
fSymbol = aSymbol;
fTime = aTime;
fBasePrice = new USDollars(aBasePrice);
}
public Object field(int aIndex)
{
return (aIndex == 0)? fSymbol
: (aIndex == 1)? fTime
: (aIndex == 2)? fBasePrice
: (aIndex == 3)? new Integer(4) // comment out this line and it compiles
: "?";
}
}
final class USDollars
implements Comparable<USDollars> // comment out this line and it compiles
{
private int cents;
public USDollars() { this(0); }
public USDollars(int cents) { this.cents = cents; }
public USDollars(int dollars, int cents) { this(cents + 100*dollars); }
public int cents() { return cents; }
// #Override
public int compareTo(USDollars other) { return this.cents - other.cents; }
}
By the way, a quick fix was to modify the code as follows (ugly but it works):
public Object field(int aIndex)
{
if (aIndex == 2)
return fBasePrice;
return (aIndex == 0)? fSymbol
: (aIndex == 1)? fTime
: (aIndex == 3)? new Integer(4) // comment out this line and it compiles
: "?";
}