Home Features Docs Blog Support GitHub

Generated bindings and Java generics

Currently generated bindings are forcing to use explicit casts in the Java code, which produces some cluttering as well as a lot of compiler warnings.

For example:

NSMutableArray a = NSMutableArray.alloc().init();

I can’t specify type NSMutableArray without explicitly casting return value of .init() method.

This is because init() is declared like this:

public native NSMutableArray<?> init();

I’d suggest to change generated code to this:

public native <T> NSMutableArray<T> init();

So, Java compiler will be able to deduce the return value at the assignment:

NSMutableArray<String> a = NSMutableArray.alloc().init();

Also, in NSArray:

public static native <_ObjectType> NSArray<?> arrayWithObjects(...)

Should be:

public static native <_ObjectType> NSArray<_ObjectType> arrayWithObjects(...)

and Object… vararg param there should be also _ObjectType.

Same issue with NSMutableDictionary, NSDictionary…

Please let me know if those are doable, in that case I will add a few more examples from standard ios frameworks I bumped at.

It should be doable, we created an issue to track this, please add more examples the you would like us to support:


Thank you Gergely.
Also it seem like generated static alloc() factory method might need to be changed to something like this (all the way up in the object hierarchy):

public static native <T> T alloc();

this is to allow specific typing in the inherited classes. But it is going to be a backward incompatible change, i.e. bindings have to be regenerated.

Though this one might go away if you replace those alloc’s with contructors as it was described in one of the open issues. Not sure what’s the timeframe for that.

This is also from one of MOE examples:

The NSLayoutConstraint.constraintsWithVisualFormatOptionsMetricsViews() method is declared like this:

public static native NSArray<? extends NSLayoutConstraint> constraintsWithVisualFormatOptionsMetricsViews(
        String format, @NUInt long opts, NSDictionary<String, ?> metrics, NSDictionary<String, ?> views);

So, I have to explicitly cast like this:

NSMutableArray<NSLayoutConstraint> constraints = (NSMutableArray<NSLayoutConstraint>) NSMutableArray.alloc().init();

NSArray<NSLayoutConstraint> cons1 = (NSArray<NSLayoutConstraint>) NSLayoutConstraint.constraintsWithVisualFormatOptionsMetricsViews( //
			"H:|-12-[tabs]-12-|", 0, null, views);

I think changing above method declaration to this would help:

public static native NSArray<NSLayoutConstraint> constraintsWithVisualFormatOptionsMetricsViews(
        String format, @NUInt long opts, NSDictionary<String, ?> metrics, NSDictionary<String, ?> views);

Foundation.CFBridgingRelease() declared like this:

public static native Object CFBridgingRelease(ConstVoidPtr X);

Please update to:

public static native <T> T CFBridgingRelease(ConstVoidPtr X);