user3464741 user3464741 - 4 months ago 8
Java Question

Mapping between Java's wrapper classes and Ceylon basic types

When a ceylon module imports "java.base" "8" it doesn't see the original java.lang classes, but it gets something else.

So when I want a parsing from a java string to a java integer I have to cast java string to ceylon string and then parse it into java integer.

module.ceylon:

native("jvm")
module mod "1.0.0" {
import java.base "8";
}


run.ceylon:

import java.lang{
JI = Integer,
JS = String,
}



// strange:
// java String constructor expects ceylon strings
// in pseudo dotted ceylon : java.lang.String(ceylon.language.String s)
JS t = JS("fdsf" of String);

// very strange:
// javas base library expects ceylon base types:
// java.lang.Integer.valueOf(ceylon.language.String s)


JI ji = JI.valueOf(t.string);

// Where t is a java String.

// strange like an elephant:
// JI.valueOf(t.string) returns a java type.
// for some purposes it's ok,
// but where can I buy the complete documentation ???


I'm citing Ceylon:Interoperation / Gotcha again!:

There is no mapping between Java's wrapper classes like java.lang.Integer or java.lang.Boolean and Ceylon basic types,
so these conversions must be performed explicitly by calling, for example, intValue() or booleanValue(), or by explicitly
instantiating the wrapper class, just like you would do in Java when converting between a Java primitive type and its wrapper class."

So, while being complicated it still works. But what can I do when I want
a direct conversion between java types not involving String.

This causes a problem, because there's no simple analog to t.string in ceylon, e.g. no "t.int" or "t.float".

So, there's a conversion between java and ceylon. But the price is high: The direct conversion (cast or parse) between java types is lost.

So please show how to achieve a direct conversion between java type (primitive and wrapped). I'm not talking about arrays and other stuff contained in ceylon.interop.java.

It's not easy to find around in the java.lang api, because type mapping rules are applied incompletly:

JI ji = JI.valueOf(t.string);


On the one hand "valueOf" expects a ceylon input, but on the other hand it returns a java value.
Why not the same as in the original java.lang, i.e. a conversion among java types only? Are there intuitive rules?

Could you please give a full documentation of the differences between the original java.lang and the java.lang as seen from ceylon?

How can I get the complete documentation of java.base as seen from ceylon (when not working in eclipse), generating one from reflection... ?

Answer

I’m not sure how to answer your question, because you’re saying a lot that isn’t really a question, and then you’re asking several questions too. But here goes:

So please show how to achieve a direct conversion between java type (primitive and wrapped). I'm not talking about arrays and other stuff contained in ceylon.interop.java.

import ceylon.language {
    CInteger=Integer
}
import java.lang {
    JInteger=Integer
}

shared void run() {
    CInteger ci1 = 1;
    JInteger ji1 = JInteger(ci1);
    JInteger ji2 = JInteger.valueOf(ci1);
    CInteger ci2 = ji1.intValue();
}

You can use the Java wrapper class’ constructor or the static valueOf method. To convert back, use intValue().

type mapping rules are applied incompletly:

They are not. The rules are: j.l.String and the primitive types (int, double etc.) are mapped to their Ceylon equivalents. All other types – including, as stated in

There is no mapping between Java's wrapper classes like java.lang.Integer or java.lang.Boolean and Ceylon basic types,

the wrapper classes – are not mapped.

(EDIT: OP edited in a question about ceylon.language::Integer… that’s not a Java type, nor a wrapper type. It’s exactly what it is.)

The Java signature java.lang.Integer valueOf(java.lang.String) is therefore mapped to the Ceylon signature java.lang::Integer valueOf(ceylon.language::String), because java.lang.String is mapped and java.lang.Integer isn’t. The Integer constructor is mapped from java.lang.Integer Integer(int) to java.lang::Integer Integer(ceylon.language::Integer), because the primitive type int is mapped, but the wrapper class java.lang.Integer isn’t. This is exactly what the documentation tells you.

Could you please give a full documentation of the differences between the original java.lang and the java.lang as seen from ceylon?

http://ceylon-lang.org/documentation/1.2/reference/interoperability/type-mapping/

How can I get the complete documentation of java.base as seen from ceylon (when not working in eclipse), generating one from reflection... ?

I don’t think this is available, though it would probably be useful…