Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Float instead of float (Primitive type) when implementing Parcelable

Requirement: Find out if price is null. Since a primitive float data type cannot be checked for null since its always 0.0, I opted out to use Float instead, as it can be checked for null.

public class QOptions implements Parcelable {
    public String text;
    public Float price;
}

protected QOptions(Parcel in) {
    text = in.readString();
    unit_price = in.readFloat();
}

@Override
public void writeToParcel(Parcel parcel, int i) {
    parcel.writeString(this.text);
    parcel.writeFloat(this.price);
}

However, since the class also implements Parcelable, the writeToParcel crashes with the following exception:

Attempt to invoke virtual method 'float java.lang.Float.floatValue()' on a null object reference

And the exception points to this line:

parcel.writeFloat(this.price);

How can I use the Float data type along with writeToParcel and not cause the exception? Or is there a better way to accomplish my requirement? I just need the price to be null if it's null.

like image 780
Dinuka Jay Avatar asked Oct 17 '25 11:10

Dinuka Jay


2 Answers

You can handle it in the below manner.

@Override
public void writeToParcel(Parcel dest, int flags) {
    if (price == null) {
        dest.writeByte((byte) (0x00));
    } else {
        dest.writeByte((byte) (0x01));
        dest.writeFloat(price);
    }
}

To read the value of float -

unit_price = in.readByte() == 0x00 ? null : in.readFloat();
like image 149
Kapil G Avatar answered Oct 20 '25 01:10

Kapil G


Decimal types have a number of special values: NaN, negative and positive infinities. You can use those values to indicate null:

if (price == null) {
  parcel.writeFloat(Float.NaN);
} else {
  parcel.writeFloat(price);
}

And when reading:

float p = parcel.readFloat();
if (Float.isNaN(p)) {
  price = null;
} else {
  price = p;
}

NaN means "not a number", so it kind-of fits thematically for serializing things.

Unlike the solution, provided by @Kapil G, this approach does not waste additional 4 bytes for nullability flag (each call to writeByte() actually stores entire int in Parcal for performance reasons).

like image 43
user1643723 Avatar answered Oct 20 '25 02:10

user1643723