Passing enums through aidl interfaces - java

As enums aren't primitive types, what's the most effective way to pass an enum through an aidl interface in Android? Is there a way to convert the enum to an ordinal first?

I simply use
String enumString = myEnum.name()
(with MyEnum as enum and myEnum as value) to get the String representation and then
MyEnum myEnum = MyEnum.valueOf(enumString)
to reconstruct the enum from the String representation.
Using Ordinals may be a wee bit faster but if I may add Enums later, this is more likely to break old code.
//Edit: As I don't like to have String as return type, I now implemented Parcellable like mentioned here: Passing enum or object through an intent (the best solution)
import android.os.Parcel;
import android.os.Parcelable;
enum InitResponse implements Parcelable {
// Everything is fine.
SUCCESS,
// Something else
FOO;
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(final Parcel dest, final int flags) {
dest.writeString(name());
}
public static final Creator<InitResponse> CREATOR = new Creator<InitResponse>() {
#Override
public InitResponse createFromParcel(final Parcel source) {
return InitResponse.valueOf(source.readString());
}
#Override
public InitResponse[] newArray(final int size) {
return new InitResponse[size];
}
};
}

Non primitive types, other than String, require a directional indicator. Directional indicators include in, out and inout.
Take a look at the official documentation for that: http://developer.android.com/guide/developing/tools/aidl.html#aidlsyntax
Also, you can consider passing the String or ordinal representation of the enum and translate it back when needed. This is taken from the Effective Java 2nd edition:
// Implementing a fromString method on an enum type
private static final Map<String, Operation> stringToEnum = new HashMap<String, Operation>();
static { // Initialize map from constant name to enum constant
for (Operation op : values())
stringToEnum.put(op.toString(), op);
} // Returns Operation for string, or null if string is invalid
public static Operation fromString(String symbol) {
return stringToEnum.get(symbol);
}
In the case above, Operation is an enum.
To get the ordinal of an enum consider this example:
public enum Badges{
GOLD, SILVER, BRONZE;
}
// somewhere else:
int ordinal = Badges.SILVER.ordinal();// this should be 1

Yes, you can pass enums through AIDL, but you do have to implement Parcelable on the enum type.
1: A Parcelable implementation.
public enum RepeatMode implements Parcelable {
NoRepeat,
RepeatAll,
RepeatTrack,
;
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(toInteger());
}
#Override
public int describeContents() {
return 0;
}
public static final Creator<RepeatMode> CREATOR = new Creator<RepeatMode>() {
#Override
public RepeatMode createFromParcel(Parcel in) {
return RepeatMode.fromInteger(in.readInt());
}
#Override
public RepeatMode[] newArray(int size) {
return new RepeatMode[size];
}
};
public int toInteger() { return this.ordinal(); }
public static RepeatMode fromInteger(int value)
{
return values()[value];
}
}
An import:
RepeatMode.aidl:
package com.cyberdyne.media;
parcelable RepeatMode;
And remember to mark enum arguments as in arguments.
Kind of obvious when you think about it. But I'm betting Google doesn't use a whole lot of enums in IBinder interfaces. I do it though. (Thank you Android studio for providing "Implement Parcelable", which doesn't work entirely for enums, but makes things relatively easy).
Discursus on Android enums:
Best practice recommendations against enums in Android were withdrawn many moons ago. You're trading about 200 bytes of executable for horrible horrible code. Phones have come a long way since Android 1.0. It's a no-brainer. Use enums. (Or use the insane Kotlin-driven attribute system that Google uses. Good luck with that.)
Official Java Lore dating back to the Original Java language spec discourages the use of naked ordinal(). The reasoning: maintainers in the deep future may unwittingly re-order the ordinals and break stuff. Frankly, I think that's pompous Java bogosity. I struggled with this for a long time, and after much soul-searching, I caved in.
public enum Badges {
GOLD,SILVER, BRONZE; // Must match #array/badge_states
public int toInteger() { return this.ordinal(); }
public static Badges fromInteger(int value) { return values()[value]);
}
If nothing else, it marks the class as one that probably persists integers. And a comment never hurts, and it makes the receiving end of marshalled enums a bit prettier (and just a tiny bit safer).

Related

It is posible to improve this Java Generics scenario [duplicate]

I have a generic interface like this:
interface A<T> {
T getValue();
}
This interface has limited instances, hence it would be best to implement them as enum values. The problem is those instances have different type of values, so I tried the following approach but it does not compile:
public enum B implements A {
A1<String> {
#Override
public String getValue() {
return "value";
}
},
A2<Integer> {
#Override
public Integer getValue() {
return 0;
}
};
}
Any idea about this?
You can't. Java doesn't allow generic types on enum constants. They are allowed on enum types, though:
public enum B implements A<String> {
A1, A2;
}
What you could do in this case is either have an enum type for each generic type, or 'fake' having an enum by just making it a class:
public class B<T> implements A<T> {
public static final B<String> A1 = new B<String>();
public static final B<Integer> A2 = new B<Integer>();
private B() {};
}
Unfortunately, they both have drawbacks.
As Java developers designing certain APIs, we come across this issue frequently. I was reconfirming my own doubts when I came across this post, but I have a verbose workaround to it:
// class name is awful for this example, but it will make more sense if you
// read further
public interface MetaDataKey<T extends Serializable> extends Serializable
{
T getValue();
}
public final class TypeSafeKeys
{
static enum StringKeys implements MetaDataKey<String>
{
A1("key1");
private final String value;
StringKeys(String value) { this.value = value; }
#Override
public String getValue() { return value; }
}
static enum IntegerKeys implements MetaDataKey<Integer>
{
A2(0);
private final Integer value;
IntegerKeys (Integer value) { this.value = value; }
#Override
public Integer getValue() { return value; }
}
public static final MetaDataKey<String> A1 = StringKeys.A1;
public static final MetaDataKey<Integer> A2 = IntegerKeys.A2;
}
At that point, you gain the benefit of being a truly constant enumeration value (and all of the perks that go with that), as well being an unique implementation of the interface, but you have the global accessibility desired by the enum.
Clearly, this adds verbosity, which creates the potential for copy/paste mistakes. You could make the enums public and simply add an extra layer to their access.
Designs that tend to use these features tend to suffer from brittle equals implementations because they are usually coupled with some other unique value, such as a name, which can be unwittingly duplicated across the codebase for a similar, yet different purpose. By using enums across the board, equality is a freebie that is immune to such brittle behavior.
The major drawback to such as system, beyond verbosity, is the idea of converting back and forth between the globally unique keys (e.g., marshaling to and from JSON). If they're just keys, then they can be safely reinstantiated (duplicated) at the cost of wasting memory, but using what was previously a weakness--equals--as an advantage.
There is a workaround to this that provides global implementation uniqueness by cluttering it with an anonymous type per global instance:
public abstract class BasicMetaDataKey<T extends Serializable>
implements MetaDataKey<T>
{
private final T value;
public BasicMetaDataKey(T value)
{
this.value = value;
}
#Override
public T getValue()
{
return value;
}
// #Override equals
// #Override hashCode
}
public final class TypeSafeKeys
{
public static final MetaDataKey<String> A1 =
new BasicMetaDataKey<String>("value") {};
public static final MetaDataKey<Integer> A2 =
new BasicMetaDataKey<Integer>(0) {};
}
Note that each instance uses an anonymous implementation, but nothing else is needed to implement it, so the {} are empty. This is both confusing and annoying, but it works if instance references are preferable and clutter is kept to a minimum, although it may be a bit cryptic to less experienced Java developers, thereby making it harder to maintain.
Finally, the only way to provide global uniqueness and reassignment is to be a little more creative with what is happening. The most common use for globally shared interfaces that I have seen are for MetaData buckets that tend to mix a lot of different values, with different types (the T, on a per key basis):
public interface MetaDataKey<T extends Serializable> extends Serializable
{
Class<T> getType();
String getName();
}
public final class TypeSafeKeys
{
public static enum StringKeys implements MetaDataKey<String>
{
A1;
#Override
public Class<String> getType() { return String.class; }
#Override
public String getName()
{
return getDeclaringClass().getName() + "." + name();
}
}
public static enum IntegerKeys implements MetaDataKey<Integer>
{
A2;
#Override
public Class<Integer> getType() { return Integer.class; }
#Override
public String getName()
{
return getDeclaringClass().getName() + "." + name();
}
}
public static final MetaDataKey<String> A1 = StringKeys.A1;
public static final MetaDataKey<Integer> A2 = IntegerKeys.A2;
}
This provides the same flexibility as the first option, and it provides a mechanism for obtaining a reference via reflection, if it becomes necessary later, therefore avoiding the need for instantiable later. It also avoids a lot of the error prone copy/paste mistakes that the first option provides because it won't compile if the first method is wrong, and the second method does not need to change. The only note is that you should ensure that the enums meant to be used in that fashion are public to avoid anyone getting access errors because they do not have access to the inner enum; if you did not want to have those MetaDataKeys going across a marshaled wire, then keeping them hidden from outside packages could be used to automatically discard them (during marshaling, reflectively check to see if the enum is accessible, and if it is not, then ignore the key/value). There is nothing gained or lost by making it public except providing two ways to access the instance, if the more obvious static references are maintained (as the enum instances are just that anyway).
I just wish that they made it so that enums could extend objects in Java. Maybe in Java 9?
The final option does not really solve your need, as you were asking for values, but I suspect that this gets toward the actual goal.
If JEP 301: Enhanced Enums gets accepted, then you will be able to use syntax like this (taken from proposal):
enum Primitive<X> {
INT<Integer>(Integer.class, 0) {
int mod(int x, int y) { return x % y; }
int add(int x, int y) { return x + y; }
},
FLOAT<Float>(Float.class, 0f) {
long add(long x, long y) { return x + y; }
}, ... ;
final Class<X> boxClass;
final X defaultValue;
Primitive(Class<X> boxClass, X defaultValue) {
this.boxClass = boxClass;
this.defaultValue = defaultValue;
}
}
By using this Java annotation processor https://github.com/cmoine/generic-enums, you can write this:
import org.cmoine.genericEnums.GenericEnum;
import org.cmoine.genericEnums.GenericEnumParam;
#GenericEnum
public enum B implements A<#GenericEnumParam Object> {
A1(String.class, "value"), A2(int.class, 0);
#GenericEnumParam
private final Object value;
B(Class<?> clazz, #GenericEnumParam Object value) {
this.value = value;
}
#GenericEnumParam
#Override
public Object getValue() {
return value;
}
}
The annotation processor will generate an enum BExt with hopefully all what you need!
if you prefer you can also use this syntax:
import org.cmoine.genericEnums.GenericEnum;
import org.cmoine.genericEnums.GenericEnumParam;
#GenericEnum
public enum B implements A<#GenericEnumParam Object> {
A1(String.class) {
#Override
public #GenericEnumParam Object getValue() {
return "value";
}
}, A2(int.class) {
#Override
public #GenericEnumParam Object getValue() {
return 0;
}
};
B(Class<?> clazz) {
}
#Override
public abstract #GenericEnumParam Object getValue();
}

Use Object class to achieve polymorphism in math operations

I want to make good use of polymorphism in java when implementing math operations between objects of math classes.
I got from the answers in How to add two java.lang.Numbers?
that the general solution when using java.lang.Number is to know or check the real objects class and make the appropriate hardcoded conversion to float, int, etc.
But this approach actually is not very object oriented. The java language designers chose to give the java.lang.Number class and its derivatives a set of methods floatValue(), intValue() and so on.
In light of this, Is my proposed approach, below, not going to work?.
To implement mathematical operations in a seamless way I want to to rewrite the Number class Hierarchy to allow to do something like this:
MyNumber a = b.getValue() + c.getValue();
where the real type of b and c don't matter
The base class would be:
public abstract class MyNumber {
protected Object mValue;
public abstract <N> N getValue();
}
And, for example, my integer class would look like:
public class MyInteger extends MyNumber {
public MyInteger(int value) {
mValue = value;
}
#Override
public Integer getValue() {
return (Integer) mValue;
}
}
and similarly for MyFloat, MyDouble, etc.
It will not work with different types.
public class MyInteger extends MyNumber {
public MyInteger(int value) {
mValue = value;
}
#Override
public Integer getValue() {
return (Integer) mValue;
}
}
public class MyFloat extends MyNumber {
public MyFloat(float value) {
mValue = value;
}
#Override
public Float getValue() { // first issue: types don't match. can't override
return (float) mValue; // second issue: type won't match with other getValue methods, arithmetic will fail
}
}
Your problem is even before the arithmetic. You'll need to use generics, or some kind of type-resolving and/or type-converting mechanis to get past this issue.
Firstly, overriding methods need to have matching signatures, and Types are part of that signature.
Secondly, after having a single type, Java does not have operator overloading. Therefore you will need to implement a method that MyNumber has that can take your two Generic or high level Object's and do that type casting or conversion itself.

Converting int to Enum in Java reflection

This might look similar to a few other questions but so far I have not found a solution..
I am using reflection to parse my JSONs into different classes and it saves me a lot of effort from writing class-specific parsing code, all the ints, longs, strings, and Calendars etc are easy to deal with, but now I find myself in an hell of Enum specific castings
something like:
else if (field.getType().isAssignableFrom(TransactionType.class)){
field.set(representation, TransactionType.fromInt(Integer.parseInt(value, 10)));
}
the problem is that enums are stored as integers in the JSON, and I can not find a generic way to parse or cast those integers back to enums when I don't know what enum it specifically is, and I have quite a few enums so 70% of my parsing code are now dedicated to checking enum types...
is there a way that, given only field.getType().isEnum() == true, parse the int value to the enum type of that field
the enum type is declared as:
public static enum TransactionType{
cashback(0),deposit(1),withdraw(2),invitation(3);
public int code;
TransactionType(int code){
this.code = code;
}
private final static TransactionType[] map = TransactionType.values();
public static TransactionType fromInt(int n){
return map[n];
}
}
the JSON can be a bit complicated, but enum related fields has formats as:
{transactionType: 1, someOtherEnumType: 0}
Heres how I would approch this given the information provided. Use a helper method that would sit outside your enum types that can convert any enum type that implements some interface.
public static interface Codeable {
public int getCode();
}
public static enum TransactionType implements Codeable {
cashback(0),deposit(1),withdraw(2),invitation(3);
public int code;
TransactionType(int code) {
this.code = code;
}
#Override
public int getCode() {
return code;
}
}
public static <T extends Codeable> T fromCodeToEnum(int code, Class<T> clazz) {
for(T t : clazz.getEnumConstants()) {
if(t.getCode() == code) {
return t;
}
}
return null;
}
public static void main(String [] args) {
TransactionType type = fromCodeToEnum(1, TransactionType.class);
System.out.println(type); // deposit
}
Edit: Or of course you can just get the enum values and iterate through them. This could be placed wherever you want.
public static TransactionType findTransactionTypeByCode(int code) {
for(TransactionType t : TransactionType.values()) {
if(t.getCode() == code) {
return t;
}
}
return null;
}
Java do not support the implicit cast from literal to value.
Then enum in Java has method ordinal(), that returns int value.
Returns the ordinal of this enumeration constant (its position in its enum declaration, where the >initial constant is assigned an ordinal of zero).
An unsafe solution
if(field.getType().isEnum()) {
Object itemInstance = field.getType().getEnumConstants()[ordinal];
}
How ever it is not recommended to us it at it was designed as part of API.
The recommendation for this case is to define in the definition of enum.
enum MyEnum {
ITEM(1);
private final int index;
MyEnum(int index) {
this.index;
}
}
And then you should implement additional logic to serialize and deserialize, based for example on interface with default method.
interface SerializableEnum<E extends Enum<E>> {
Class<E> getType();
default E valueOf(int ordinal) {
return getType().getEnumConstants()[ordinal];
}
}
Note that the best solution is to serialize the enum not via number but via its name.
Class.getEnumConstants() is what you need.
Class<?> cls = field.getType();
if (cls.isEnum()) {
field.set(representation,
cls.getEnumConstants()[Integer.parseInt(value, 10)]);
}

How do I define the return type inside a Java generics method?

I have a generic method, for example:
public static<T> T execute(...) {
...
}
How can I define what type T is in the method body? For example:
if (T == String) {
// do something with strings
// return string;
}
if (T == Bitmap) {
// do something with bitmap
// return bitmap;
}
I tried the following, but it didn't work:
T par = null;
if(par instanceof String) {
// do something with strings
// return string;
}
I tried declaring par like below, but that didn't work either.
T par = (T) null;
T par = (T) new Object();
You could probably do something like this:
public static <T> T execute(Class<T> t) {
if(String.class == t) {
}
}
If your code only supports a discrete set of data types, you don't want to use generics. As mentioned in the comments on the original post, this situation calls for overloaded method calls.
Consider, for example, a situation where you support Strings, Integers, and Doubles, but you don't have specific logic for other data types. You would define your methods such as:
public static String execute(String s) { ... }
public static Integer execute(Integer i) { ... }
public static Double execute(Double d) { ... }
public static Object execute(Object o) { ... }
The first three methods would define the logic for the three discrete data types you do support, while the final would define logic and/or error handling for any other data types you do not support. (Of course, this doesn't cover primitives not of int or double type, but this is just an example.)
Generics were initially added to Java to support a Collection knowing exactly what it contained. It was a way of guaranteeing that a List held only Strings by declaring it a List<String>, for example. This capability was then extended, but the basic concept held -- guarantee that if you put an unknown object of type X in, even if you don't know what X is at compile time, you can write logic for getting that same type X out. (This article is an interesting read, if out-dated.)
This does not mean it should be used where the logic applied in a method or class is dependent on the data type of the input. It should be used where it doesn't matter the incoming data type, and the same logic will be applied consistently across the unknown data type X. So if you have different logic for String than Doubles, you should not be using generics.
tl;dr:
Since the original post indicated different logic based on the data type of the input parameter, therefore, generics are not appropriate to be used. Overloading the execute method based on the supported data types should be used instead.
T Here is known as Type Parameters.
// here will define the type of T in the method go()
public interface Comparable<T> {
public int compareTo(T t) {
// do something...
}
}
For eg:
I am having a class Song, and i want to sort the songs on the basis of its title.
public class Song implements Comparable<Song> {
private String title;
public void compareTo(Song s) {
title.compareTo(s.title());
}
public void setTitle(String s) {
this.title = s;
}
public void getTitle() {
return this.title;
}
public String toString() {
return getTitle();
}
}
If you're splitting the functionality in code that way already, and the inputs are the same, you'd probably be well served with different functions. So instead of(using Jeshurun's answer)
public static <T> T execute(Class<T> t)
{
if(String.class == t) {
}
}
BitMap b = execute(BitMap.class);
You would have
public BitMap bitmapExecute(...)
{
commonWork();
//do bitmap stuff
}
public String stringExecute(...)
{
commonWork();
//do String stuff
}
BitMap b = bitmapExecute(...);
String s = stringExecute(...);
If there's a large block of common code, with only a small section different based on type, you can move that common code to its own function.
public someObject commonWork(...)
{
//Do common stuff
}
As long as you are making the decision about the type at compile time, you shouldn't have to have instanceof blocks.

Java Type Erasure Problem

I've made an example to demonstrate my problem:
Metrical.java
public interface Metrical<T>
{
double distance(T other);
}
Widget.java
public class Widget implements Metrical<Widget>
{
private final double value;
public Widget(double value) { this.value = value; }
public double getValue() { return value; }
public double distance(Widget other) { return Math.abs(getValue() - other.getValue()); }
}
Pair.java
public class Pair<T>
{
private final double value;
private final T object1, object2;
public Pair(T object1, T object2, double value)
{
this.object1 = object1;
this.object2 = object2;
this.value = value;
}
public T getObject1() { return object1; }
public T getObject2() { return object2; }
public double getValue() { return value; }
}
Algorithm.java
import java.util.Set;
public class Algorithm<T extends Metrical<T>>
{
public void compute(Set<T> objects)
{
}
public void compute(Set<Pair<T>> pairs)
{
}
}
So, in Algorithm.java, Set< Pair< T >> is being seen as a Set< T > and thus I am having type erasure problems. However, is there any way I can get away with something like this without naming the methods differently? Both variants of the algorithm are meant to operate on T's, but I need to allow for different arguments. They compute the same thing, so in an effort to avoid confusion, I would rather not name them differently. Is there any way to accommodate this?
No there isn't.
You have to remember that someone could call your method with just a vanilla Set, in which case which one would be called?
That's why you can't do it. Just like you can't do:
interface A {
void blah(Set set);
void blah(Set<T> set);
}
Same problem.
The type information isn't available at runtime (ie type erasure).
Sorry, the bad news is that you cannot do this:
public class Algorithm<T extends Metrical<T>> {
public void compute(Set<T> objects) {
}
public void compute(Set<Pair<T>> pairs) {
}
}
Due to erasure, both will erase to the same signature. There is no way around this short of renaming one of the methods.
Sadly, this is the major area where Java Generics falls down... there is just no good solution.
I've generally resorted to making a new class, with the interface as Set<Pair<T>>, but that wraps Set<Pair<T>> (without extending it, which would cause the same problem).
I've written an article about type erasure which can be of your interest.
It gives the common widely known solution and also a tricky way to circumvent the problem.
I don't know if it will be relevant for you. Anyway, it contains some techniques which may be useful under certain circumstances.
See also: Using TypeTokens to retrieve generic parameters
I hope it helps.
Use public class Widget<K, P> implements Metrical<K extends Widget<P>>.
public double distance(Widget other) {} becomes public double distance(Widget<P> other) {}

Categories