I'm having a really frustrating problem with SharedPreference.getBoolean in android. See the following snippet:
Map<String, ?> all = preferences.getAll();
Object x = all.get("EnableMedia");
boolean v = preferences.getBoolean("EnableMedia", (Boolean) null);
I can see in the debugger that 'x' is a Boolean and it is true.
Yet, if I execute the next line, preferences.getBoolean, it throws an exception. What gives?!
Look at this call:
preferences.getBoolean("EnableMedia", (Boolean) null);
Now look at the signature of getBoolean:
public abstract boolean getBoolean (String key, boolean defValue)
Note that it's a boolean value, not a Boolean value. So what's actually happening is your code is something like this:
Boolean tmp = null;
preferences.getBoolean("EnableMedia", tmp.booleanValue());
That will throw a NullPointerException, as you're calling a method on a null reference.
You need to pass in a valid boolean value, e.g.
preferences.getBoolean("EnableMedia", true);
Related
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.
I have a function that is supposed to return a place object, but I also need to test on whether something evaluates to false, and in addition the caller needs to know both of those pieces of information. I have the return type as Place but in Java there are no reference parameters, so if the following if-condition is true, I would like for some way to reflect that in the caller so I can check it, but I can't have more than one return type so I'm stuck as to what to do. My best shot was returning null but I just get the feeling that this is bad programming.
if ( directions.get(i).isLocked() )
Below is the complete function:
Place followDirection(String dir, boolean isLocked) {
dir = dir.toLowerCase(); // make sure the string is lowercase for comparisons
int i = 0;
for ( i = 0; i < directions.size(); i++ ) { // loop until we find a match, remember that if it's locked then we cnanot go in there
if ( directions.get(i).getDirection().equals(dir) ) {
if ( directions.get(i).isLocked() ) {
System.out.println("This room is locked, sorry");
}
else {
return directions.get(i).getToPlace(); // this means we found a match, return the destination
}
}
}
Place p = null;
return p;
}
Technically, there are two options if you don't want to return null (which does not seem bad by the way):
return an object that contains both return values
Pass in a mutable object as parameter.
The second option also feels somewhat dirty.
java is a call by value language but it is a little bit complicated. this language pass the pointers as a value and if you dont change the pointer you can change the object that pass to your function. for example if you pass an complex object to a function and in that function you change the value of a parameter of that object, the caller can see it, in your code you can pass an object than contains dir and isLocked , so you can change those parameters.
Place followDirection(MyObject obj) {
obj.dir = obj.dir.toLowerCase(); // make sure the string is lowercase for comparisons
int i = 0;
for ( i = 0; i < directions.size(); i++ ) { // loop until we find a match, remember that if it's locked then we cnanot go in there
if ( directions.get(i).getDirection().equals(obj.dir) ) {
if ( directions.get(i).isLocked() ) {
System.out.println("This room is locked, sorry");
}
else {
return directions.get(i).getToPlace(); // this means we found a match, return the destination
}
}
}
Place p = null;
return p;
}
MyObject contains :
String dir, boolean isLocked
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
}
so i have this method:
class A(){
private Boolean Flag;
public java.lang.Boolean getFlag()
{
return this.Flag;
}
public java.lang.Boolean setFlag(Boolean Flag)
{
this.Flag = Flag ;
}
}
classB(){
boolean navalFlag = fancyObj.getFlag()
form.setNavalFlag(navalFlag?"Y":"N";
}
database returns null and Flag is set to null.
What is a foolproof way where I can 100% avoid NPEs? I know Boolean to boolean casting is not a guarantee as seen from here
Update:
stepping through the code, the NPE is thrown in fancyObj.getFlag()...which doesn't make sense to me. i would expect the NPE thrown in .setNavalFlag....
What is a foolproof way where I can 100% avoid NPEs?
One foolproof way is to explicitly check for null and to not attempt to unbox the Boolean unless you know it's not null.
To take your current code as an example:
boolean navalFlag = fancyObj.getFlag()
This tries to unbox the Boolean. If it's null, you get an NPE.
The following modification will not have this problem:
Boolean navalFlag = fancyObj.getFlag()
form.setNavalFlag((navalFlag != null && navalFlag) ? "Y" : "N");
Boolean navalFlag = fancyObj.getFlag()
form.setNavalFlag((navalflag != null && navalFlag) ? "Y" : "N");
Edit of the Edit, as I had understood wrongly your comment :
See my answer to the comment: boolean navalFlag = fancyObj.getFlag() is automatically translated to boolean navalFlag = fancyObj.getFlag().booleanValue()
Change your method
public java.lang.Boolean getFlag()
{
return this.Flag;
}
to something like
public java.lang.Boolean getFlag()
{
(Flag==null) ? Boolean.FALSE : Flag;
}
Use boolean primitive type, not wrapper in your value object.
If you retrieve the value from database yourself, you will have to be careful, you will have to understand how to interpret null, normally it is false.
I tried different ways to fix this, but I am not able to fix it. I am trying to get the Boolean value of an Object passed inside this method of a checkBox:
public boolean onPreferenceChange(Preference preference, Object newValue)
{
final String key = preference.getKey();
referenceKey=key;
Boolean changedValue=!(((Boolean)newValue).booleanValue()); //ClassCastException occurs here
}
I get:
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean
Instead of casting it, you can do something like
Boolean.parseBoolean(string);
Here's some of the source code for the Boolean class in java.
// Boolean Constructor for String types.
public Boolean(String s) {
this(toBoolean(s));
}
// parser.
public static boolean parseBoolean(String s) {
return toBoolean(s);
}
// ...
// Here's the source for toBoolean.
// ...
private static boolean toBoolean(String name) {
return ((name != null) && name.equalsIgnoreCase("true"));
}
So as you can see, you need to pass a string with the value of "true" in order for the boolean value to be true. Otherwise it's false.
assert new Boolean( "ok" ) == false;
assert new Boolean( "True" ) == true;
assert new Boolean( "false" ) == false;
assert Boolean.parseBoolean( "ok" ) == false;
assert Boolean.parseBoolean( "True" ) == true;
assert Boolean.parseBoolean( "false" ) == false;
From the code you posted, and the result you are seeing, it doesn't look like newValue is a boolean. So you try to cast to a Boolean, but it's not one, so the error occurs.
It's not clear what you're trying to do. Ideally you'd make newValue a boolean. If you can't do that, this should work:
boolean newValue;
if (newValue instanceof Boolean) {
changedValue = newValue; // autoboxing handles this for you
} else if (newValue instanceof String) {
changedValue = Boolean.parseBoolean(newValue);
} else {
// handle other object types here, in a similar fashion to above
}
Note that this solution isn't really ideal, and is somewhat fragile. In some instances that is OK, but it is probably better to re-evaluate the inputs to your method to make them a little cleaner. If you can't, then the code above will work. It's really something only you can decide in the context of your solution.
If you know that your Preference is a CheckBoxPreference, then you can call isChecked(). It returns a boolean, not a Boolean, but that's probably close enough.
Here is some code from the APIDemos Device Administration sample (DeviceAdminSample.java).
private CheckBoxPreference mDisableCameraCheckbox;
public void onResume() {
...
mDPM.setCameraDisabled(mDeviceAdminSample, mDisableCameraCheckbox.isChecked());
...
}
public boolean onPreferenceChange(Preference preference, Object newValue) {
...
boolean value = (Boolean) newValue;
...
else if (preference == mDisableCameraCheckbox) {
mDPM.setCameraDisabled(mDeviceAdminSample, value);
reloadSummaries();
}
return true;
}