Closed imagejan closed 2 years ago
A question to the Java generics experts (likely @ctrueden):
Is it possible to implement a Converter<Integer, IntegerType<T>>
that can convert to sub-classes of NumericType
? Such that when you call e.g. convert(someInteger, UnsignedByteType.class)
, it would generate a new UnsignedByteType(someInteger)
, and when you call convert(someInteger, ShortType.class)
, it would create new ShortType(someInteger)
, etc. for all implemented sub-classes of IntegerType
?
Or do we need to implement an explicit converter for every ImgLib2 *Type
as present for four of them currently in imagej-server
(Double
, Float
, Integer
, Long
)?
I figure that for the other direction it should be simple, as long as we convert(IntegerType, Integer)
with the help of IntegerType.getInteger()
. So we probably need:
IntegerTypeToIntegerConverter
using getInteger()
BooleanTypeToBooleanConverter
using get()
RealTypeToDoubleConverter
using ComplexType#getRealDouble()
RealTypeToFloatConverter
using ComplexType#getRealFloat()
?What do you think?
Is it possible to implement a
Converter<Integer, IntegerType<T>>
that can convert to sub-classes ofNumericType
? Such that when you call e.g.convert(someInteger, UnsignedByteType.class)
, it would generate anew UnsignedByteType(someInteger)
, and when you callconvert(someInteger, ShortType.class)
, it would createnew ShortType(someInteger)
, etc. for all implemented sub-classes ofIntegerType
?
This is not possible in general if you only have the Class
.
If you had an instance of the concrete Type
you could call its createVariable()
method to make a new one.
If you know the Class
has a no-argument constructor that does what you need, you can use reflection to get and call that. For example, this works:
public static void main( String[] args )
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException
{
UnsignedByteType t = g( UnsignedByteType.class );
System.out.println( "t = " + t );
}
public static < T extends RealType< T > > T g( Class< T > klass )
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException
{
T t = klass.getConstructor().newInstance();
t.setReal( 2 );
return t;
}
I don't know about the performance penalty though. That should be tested...
While writing a test for an unrelated task, I discovered that org.scijava.convert.DefaultConverter
will handle conversion for:
Objects where the destination Class has a constructor which takes that Object
... which is true for most of (all?) the Number
to *Type
conversions.
As such, the converters (written by @lnyng) that I wanted to migrate from imagej-server
to here (in https://github.com/imagej/imagej-common/pull/82/commits/37fd588863d185209430503fa96b54cba4107c1d) are actually completely unnecessary (!).
The other direction (NumericType -> Number
) remains valid and necessary.
I'll try to update this pull request soon (keeping the tests for conversion in both directions, and adding just the necessary converters).
@imagejan The eventual goal was to split up the DefaultConverter
into pieces. And maybe consider whether that auto-wrapping constructor magic is actually wise... but since that's how things currently work, and we shouldn't break backwards compatibility by changing it, your plan (of not implementing the unnecessary conversion directions) sounds good to me! :+1:
@imagejan I cleaned up your work in an effort to make progress on https://github.com/imagej/pyimagej/issues/162.
Do you feel that it is necessary to keep these five tests? I guess they are special cases...
@ctrueden I rebased this over the latest master, and we have all passing tests. Can we get this merged quickly?
I'm not quite sure that the files I edited are correctly formatted, got to remember how I had set up formatting before in IntelliJ. I think I'll have to save that for tomorrow...
I actually think I got the formatting setup correctly in 6a7f8f4. Does this commit's formatting look right to you @ctrueden?
Thanks @gselzer for updating this PR!
Do you feel that it is necessary to keep these five tests? I guess they are special cases...
It's not exactly necessary, but they don't hurt, right? Just some (common) special cases to make sure they work.
It's not exactly necessary, but they don't hurt, right? Just some (common) special cases to make sure they work.
Might as well keep them then, they don't hurt to keep.
Thank you @imagejan for this work, and thank you @gselzer for spurring it forward.
This PR resolves #80 (except for the changes in result post-processing which are tracked in https://github.com/scijava/scijava-table/issues/5).
Remaining tasks:
NumberToNumericTypeConverters
by Leon Yang were just copied over fromimagej-server
; should we consider migrating their git history as well, @ctrueden ?