> So, constant numbers such as 10, 11,..., 256 are all considered
> integers by default. Then as you said the Java language specification
[quoted text clipped - 9 lines]
>
> final byte a = 10;
Both of these assignments work fine. The difference is that in the
second case, 'a' cannot be changed to a different value later. That's
what the 'final' keyword means.
The reason that final matters, in this case, is that the compiler has
certain rules for deciding when it "knows" the value of a variable.
Such variables, whose values are known to the compiler, are referred to
as compile-time constants. One of these rules is that for a variable in
an expression to be a compile-time constant, the variable has to be
declared with the 'final' qualifier. That's because you could change
the value of a non-final variable, so it isn't really a constant.
Another rule for compile-time constants says that if you multiply
together two compile-time constants, the result is also a compile-time
constant. The result is that when considering the expression 'a * b',
it is a compile-time constant *only* of both a and b are already
compile-time constants, which means they need to be declared as final.
The rule for implicit assignment conversion of the int to a byte in Java
requires that the value be a compile-time constant. So there are a
couple levels of indirection there, but that's why declaring 'a' and
'b' as final makes your code work.
> Or is the difference in the declaration of the declaration? From what
> I've gathered in my text the declaration of a byte reserves 8bits of
> space in memory while integer declarations reserve 32bits of space.
Sort of. If that mental model helps you understand the behavior of a
Java program, then go ahead and use it. However, you should understand
that it's only a model. The Java Language Specification doesn't specify
how much memory is reserved to hold variables; it only specifies the
results of doing things to variables. 8 bits would be enough memory to
correctly implement operations on the 'byte' data type, but that doesn't
mean the program couldn't reserve more.
In practice, because of the details of implementation of modern CPUs,
things are different. If you could peek inside the system as your
application runs, you'd be likely to discover that it has actually set
aside 32 bits, or perhaps even 64 bits on certain processors, to hold a
local variable declared as type 'byte'. In fact, certain details of the
Java bytecode format make this almost a sure bet for Java source that's
compiled to bytecode.
So the lesson is: mental models are fine, but don't confuse them with
reality. Especially if you start thinking about improving the memory or
time efficiency of your code at a low level, you will need to abandon
that simplistic model of what's occurring. For example, replacing use
of the 'int' data type with 'byte' for local variables is unlikely to
save memory; but doing the same for an array is a more promising
prospect.
> The number 10 in binary is represented as 00001010 correct? So if
> possible please explain how memory is being allocated and what is
> being stored.
The Java literal "10" is represented as:
0000 0000 0000 0000 0000 0000 0000 1010
That's the same as what you said, except you should remember that it's
an integer, and therefore 32 bits long. If that number is converted to
a "byte" data type (either through a cast, or an implicit assignment
conversion of a compile-time constant), then it becomes:
0000 1010
(though recall that this still may be stored in a 32-bit or even 64-bit
slot in implementation.)
> I realize this may be splitting hairs but I feel that I should make a
> valid effort to understand what is going on behind the scenes if I
> wish to become a good programmer.
Let me make a recommendation, then. You will need to come to terms with
the difference between specified behavior and actual implementation. In
this message, we've crossed that boundary several times. The original
question that you asked dealt with specification. Now we've crossed
into implementation realm. There will be no end to confusion if you mix
up the two.
All the rules about implicit and explicit conversions, etc. that have
been discussed to this point are rules created as part of the Java
programming language. They are *not*, for the most part, related to the
implementation of arithmetic in any CPU. They are chosen instead
because it creates a safer programming environment in which you are less
likely to make a mistake.
When you begin talking about actual implementation, then you need to do
one of two things: either restrict your discussion to the probability of
certain implementations, as I have done above; or pick a specific
implementation (e.g., "Sun's reference implementation of the Java
virtual machine for Windows, version 1.4.2_05") instead of just "Java".
> Oh, one more thing. If constants such as 25 are integers then is the
> uppermost limit of an integer + 1 still considered to be an integer or
> does it become a long.
Section 3.10.1 of the Java Language Specification answers your question.
It says:
A compile-time error occurs if a decimal literal of type int is
larger than 2147483648 (2^31), or if the literal 2147483648 appears
anywhere other than as the operand of the unary - operator, or if a
hexadecimal or octal int literal does not fit in 32 bits.
So an integer literal that's too large to fit in an int causes the
compiler to give an error. You can learn from the same section that
appending the letter 'L' to the end of a literal makes it of type
'long'. That would be the answer. So you can *not* write:
long val = 99999999999; // compiler error
but you can write:
long val = 99999999999L; // okay

Signature
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation