I like cups. Big cups, little cups.
Painted tea cups, huge cappuccino bowls, cups with logos from the UCLA coffeehouse. Cups I
painted myself at the "All Fired Up" pottery shop. Cups with curvy, sexy
handles. Metallic cups that I now know must never, ever go in the microwave.
So when I think of variables, I naturally think of... cups.
A variable is just a cup. It has a size, and it can hold something.
In Java, cups come in two main styles: primitive and reference.
Primitive cups hold primitive values.
Reference cups hold remote controls to objects.
We'll start with primitives. Primitive cups are like the cups they have at the coffeehouse. If you're familiar with Starbucks' you know what I mean. They come in different sizes, and each size has a name like short, tall, grande. As in, "I'd like a grande mocha java with extra whipped cream. Oh, and use non-fat milk please")
Our coffeehouse has a picture of the cups on the counter, so customers know what to order. It looks like this:
In Java, integer primitives comes in different sizes, and those sizes
have names. They look like this:
So when I think of variables, I naturally think of... cups.
A variable is just a cup. It has a size, and it can hold something.
In Java, cups come in two main styles: primitive and reference.
Primitive cups hold primitive values.
Reference cups hold remote controls to objects.
We'll start with primitives. Primitive cups are like the cups they have at the coffeehouse. If you're familiar with Starbucks' you know what I mean. They come in different sizes, and each size has a name like short, tall, grande. As in, "I'd like a grande mocha java with extra whipped cream. Oh, and use non-fat milk please")
Our coffeehouse has a picture of the cups on the counter, so customers know what to order. It looks like this:
These cups hold a value.
So instead of saying, "I'd like a tall French Roast", you say to the compiler, "I'd like an int with the number 90 please." And that's what you get. (you also have to give your cup a name, but we'll get to that later.)
So instead of saying, "I'd like a tall French Roast", you say to the compiler, "I'd like an int with the number 90 please." And that's what you get. (you also have to give your cup a name, but we'll get to that later.)
The number 90 is dropped into your int-sized cup.
But what about floating point numbers? (the things with
decimal points)
They get their own cups too.
They get their own cups too.
And there's another cup for booleans, that can store values
of true or false. And a cup for chars, that store single characters like the letter 'c' or
'z'.
In Java, each of these cups (float, char, long, etc.) is
a specific size. Byte is the smallest, double and long are the largest. Rather than
measure in milliliters (or ounces as we do in the US) Java variables have a size measured
in bits:
byte - 8 bits
short - 16 bits
int - 32 bits
long - 64 bits
short - 16 bits
int - 32 bits
long - 64 bits
All of these integer types are SIGNED. The leftmost bit
represents the sign (positive or negative) and is NOT part of the value. So with a byte,
for instance, you don't get the whole 8 bits to represent your value. You get 7. This
gives you a range, for bytes, of :
(-2 to the 7th) through (2 to the 7th) -1. Why that little -1 on the end? Because zero is in there, and zero counts as negative. Works the same way with the others.
(-2 to the 7th) through (2 to the 7th) -1. Why that little -1 on the end? Because zero is in there, and zero counts as negative. Works the same way with the others.
float - 32 bits
double - 64 bits
double - 64 bits
Floating point numbers are in the IEEE 754 standard. If
that means anything to you, great. If it doesn't, well, then, you'll just have to struggle
through the long technical dissertation on floating point numbers which I feel compelled
to insert here. What the heck, I'll skip it.
We rejoin our primitive variables, already in progress.
char - 16 bits, UNSIGNED
(Unicode format -- for English, it maps perfectly to ASCII with the high 8-bits just hanging out as a bunch of zeros)
(Unicode format -- for English, it maps perfectly to ASCII with the high 8-bits just hanging out as a bunch of zeros)
boolean - hmmmm... you're not supposed to ask. It holds a
value of true or false, but it's really stored as a numeric value, probably in a
byte-sized cup. Try not to think about the size; all you know is that it holds a boolean.
Let's get to the Really Interesting Cups... REFERENCES
In Java, if you want to stick an object in a variable,
remember that the object is created out on the garbage-collectible heap. Always. So it's
not IN the variable. There aren't giant, expandable cups which can be made big enough to
hold any object. And unlike C/C++, there aren't cups which hold the exact memory location
of the object.
In Java, objects are created on the heap, and a
REFERENCE to the object is stored in the cup. Think of it as a remote control to a
specific type of object.
At the CoffeeCorral, a customer can ask for a remote
control to a TV They ask for it like this:
"I'd like a reference to a new Sony32 television
please, and name it TV." which in Java looks like:
But notice the NAME written on the cup. The cups have
unique names. Imagine if you had a pile of remote controls, and nobody knew which one
controlled which TV. So we make people put names on their remote control cups. But the
name is not on the object -- the object has a unique ID, like a serial number, but that
isn't the same as what you name the reference! The reference name (the name on the cup) is
YOUR choice.
It's the same for primitives -- you name the cups like
this:
"I'd like a byte with the number 7, and name it x please".
"I'd like a byte with the number 7, and name it x please".
For object references, you can also ask for a self-serve
remote control... a remote control where you don't have a television object picked out
yet. You still get the remote in the cup, but you "program" that remote for a
specific television later.
In Java you say:
Sony32 tv; // declare but don't initialize with an actual Sony32 object.
It's like saying, "I'd like a reference to a Sony32
television, and name the remote 'tv', but I'll pick out the actual television
later.". You get the cup, you get the remote, but there's no object and the remote
isn't controlling ANYTHING.
In Java, a remote which refers to nothing is a reference
with a value of null.
So what's REALLY inside that cup? What's a remote
control?
In Java, remote controls are called references. They store
a value which the Java Virtual Machine (JVM) uses to get to your object. It sure looks and
feels a lot like a pointer, and it might very well be a pointer to a pointer, or...
You Can't Know. It's an implementation detail that you,
as a programmer, can't access. Don't even think about it. There's no way to use that
value other than to access the methods and variables of the actual object the reference
refers to. That's part of what makes Java safer than C/C++. You can not go directly to any
arbitrary memory location. The JVM allocates memory on your behalf, for your object, and
stores an address-like thing in the reference cup (which is most likely a 32-bit cup, but
not guaranteed to be).
If this depresses you, take a deep breath, have a nice big
cup of hot tea and get over it.
0 comments:
Post a Comment