Cast problem.

W

wybrand

Hai fellow programmers.

Can you please give me an answer to the following??

See next code-fragment:

class a {

public static void main( String [] arg ) {
short a;
int b;

// Implicit cast.
a = 65;

// Explicit cast which compiles.
a = (int)65;

// Explicit cast which does not compile.
b = (long)65;
}
}

The first statement compiles because of implicit typecasting and there
is no loss of information (65 < 2^16-1).
The third one does not compile because we do an explicit typecast and
a long is 64 bytes and an integer is 32.
Why does the second statement compile?? A integer doesn't fit in a
short, just like a long does not fit in a integer (third statement).
It looks like if a implicit typecast takes place just like the fist
statement.

Thanks in advance.

Greetings,

Wybrand.
 
J

John C. Bollinger

wybrand said:
Can you please give me an answer to the following??

See next code-fragment:

class a {

public static void main( String [] arg ) {
short a;
int b;

// Implicit cast.
a = 65;

// Explicit cast which compiles.
a = (int)65;

// Explicit cast which does not compile.
b = (long)65;
}
}

The first statement compiles because of implicit typecasting and there
is no loss of information (65 < 2^16-1).

There is no such thing as "implicit typecasting". What you see is the
operation of "assignment conversion"; see below for more information.
The third one does not compile because we do an explicit typecast and
a long is 64 bytes and an integer is 32.

There is only one kind of typecast, which in fact does appear in the
third expression. Whether or not there is a cast is not directly
relevant, however: what is relevant is the _type_ of the expression
being assigned. In that respect there is no difference whatsoever
between "b = (long) 65;" and "b = 65L;".
Why does the second statement compile?? A integer doesn't fit in a
short, just like a long does not fit in a integer (third statement).
It looks like if a implicit typecast takes place just like the fist
statement.

Again, there is no such thing as an "implicit typecast". As you have
discovered, there is no difference from the point of view of the
assignment operator between "a = 65;" and "a = (int) 65;".

Here is the definitive material, from JLS(2e), section 5.2:

Assignment conversion occurs when the value of an expression is assigned
(§15.26) to a variable: the type of the expression must be converted to
the type of the variable. Assignment contexts allow the use of an
identity conversion (§5.1.1), a widening primitive conversion (§5.1.2),
or a widening reference conversion (§5.1.4). In addition, a narrowing
primitive conversion may be used if all of the following conditions are
satisfied:

* The expression is a constant expression of type byte, short, char
or int.
* The type of the variable is byte, short, or char.
* The value of the expression (which is known at compile time,
because it is a constant expression) is representable in the type of the
variable.


Compare those rules to your examples to see that the observed behavior
of the compiler is completely in conformance with the JLS.


John Bollinger
(e-mail address removed)
 
B

bilbo

wybrand said:
Hai fellow programmers.

Can you please give me an answer to the following??

See next code-fragment:

class a {

public static void main( String [] arg ) {
short a;
int b;

// Implicit cast.
a = 65;

// Explicit cast which compiles.
a = (int)65;

// Explicit cast which does not compile.
b = (long)65;
}
}

The first statement compiles because of implicit typecasting and there
is no loss of information (65 < 2^16-1).
The third one does not compile because we do an explicit typecast and
a long is 64 bytes and an integer is 32.
Why does the second statement compile?? A integer doesn't fit in a
short, just like a long does not fit in a integer (third statement).
It looks like if a implicit typecast takes place just like the fist
statement.

Good observation. The Java language specification specifies the above
behavior, but I have no idea why. Section 5.2 of the spec says that in
an assignment conversion, a narrowing primitive conversion may take
place if all three of the following conditions are met, otherwise you
get a compile error:

* The expression [right hand side] is a constant expression of type
byte, short, char or int.
* The type of the variable [left hand side] is byte, short, or char.
* The value of the expression (which is known at compile time, because
it is a constant expression) is representable in the type of the
variable.

As you can see, your first two assignments meet the conditions. The
third doesn't because variable type is not byte, short, or char, and
the expression type is not byte, short, char or int.

Here's a link to the language specification.
http://java.sun.com/docs/books/jls/second_edition/html/jTOC.doc.html
See section 5.2 for a description of assignment conversions, and
section 5.1.3 for a description of narrowing primitive conversions.

Does anyone know the rationale for why a narrowing conversion is
allowed for certain types and not others?
 
T

Tor Iver Wilhelmsen

a = (int)65;

This is in effect a no-op: The 65 is already an int. The compiler
treats numeric constants like that the same way whether there is the
unnecessary cast or not there.
 
J

John C. Bollinger

bilbo said:
Does anyone know the rationale for why a narrowing conversion is
allowed for certain types and not others?

Only the language designers know for sure, if they even remember. My
guess would be that it is related to the fact that there is no way in
Java to express a literal of type byte or short, and that char comes
along for the ride as an additional "small" integral type. In other
words, it is allowed in those cases as a programming convenience, and
designed in such a way that there are no special cases. It applies to
all compile-time constant values of the "small integer" type, and to all
variables of the same category of types (for which narrowing might be
required).

Castless narrowing of long to int is not permitted (I speculate) because
to have a constant long in the first place you must have explicitly
specified that type. It is thus reasonable that Java wants you to
declare what you are doing by means of a cast when you narrow a long; if
you write such an assignment without a cast it is reasonably likely to
reflect a design or coding error.

Narrowing of double to float is not permitted without a cast because in
general it loses precision.

References can never be narrowed in Java without a cast; this is a
fundamental design feature of the language.


John Bollinger
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Type cast problem. 2
EJB Bindings - Class Cast Exception 0
cast musings 19
cleaner alternative for cast 111
cast question 4
Is a function argument an implicit cast? 9
Minimum Total Difficulty 0
cast problem 5

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top