Java Data Types, Casting and References
Context: FIT2099_MOC · what a variable can hold and how it’s stored · primitives vs objects · statically typed
Quick Revision
- 🎯 Objective: classify a variable as primitive or reference ➔ primitives store a value, references store a pointer to a heap object.
- 📦 Core Components: 8 primitives +
String/classes | value vs reference | widening (auto) vs narrowing (manual) casts | class vs local scope.- ⚡ Key Constraint: the value-vs-reference distinction —
int i = 5holds 5;Integer i = new Integer(5)holds an address to a heap block.
📝 How It Works
1. Primitive Types (store a value directly)
- Integers ➔
byte(8) ·short(16) ·int(32) ·long(64) bits. - Floating point ➔
float(32-bit IEEE) ·double(64-bit IEEE). - Other ➔
boolean(true/false) ·char(single Unicode char). - Not classes ➔ primitives have no attributes/methods.
2. Reference Types (store a pointer)
- Classes/interfaces ➔
String(capital S — a class, not a primitive), plus any class you define. - Value vs reference ➔ a primitive variable is its value; a reference variable holds the address of a heap-allocated object that stores the attributes.
- A class is (almost) a type ➔ you declare variables of it:
MilkContainer mc;(a reference, initially null).
3. Casting
- Widening (automatic) ➔ smaller → larger:
byte → short → char → int → long → float → double;double d = anInt;. - Narrowing (manual) ➔ larger → smaller needs an explicit cast:
int i = (int) aDouble;(may lose data).
4. Scope
- Class variable/field ➔ declared in the class, visible to all its methods.
- Local variable ➔ declared inside a method/block
{}, exists only there.
5. Equality: == vs .equals()
==➔ compares the reference (memory address) — are these the same object?.equals()➔ compares the value (e.g. aString’s character sequence) — do they mean the same?- String Pool ➔ Java shares identical string literals, so
"test" == "test"istrue(same pooled address); butnew String("test") == new String("test")isfalse(two distinct heap objects), while.equals()istruefor both. - Rule ➔ for objects (especially
String), always use.equals()for value comparison; reserve==for primitives and identity checks.
⚖️ Core Decision Matrix
Primitive (int) | Reference (Integer, String, your class) | |
|---|---|---|
| stores | the value itself | an address (pointer) to a heap object |
| has methods? | no | yes (it’s an object) |
| default | 0/false | null |
When It Flips: widening is safe (no data loss) so Java does it automatically; narrowing can truncate, so Java forces you to ask for it with
(type)— the cast is you accepting the risk.
🧠 Active Recall
What's the difference in what an
intvariable and anIntegervariable actually store?Answer
- Short answer: An
int(primitive) stores the value5directly in its memory slot; anInteger(reference type) stores an address pointing to a heap block that holds the object’s data.- Why: Value vs reference ➔ primitives are the value; objects are reached through a pointer, which matters for aliasing and equality later.
Why is
double d = anInt;allowed automatically butint i = aDouble;is not?Answer
- Short answer: int→double is widening (no data lost), so it’s automatic; double→int is narrowing (fraction lost), so it needs an explicit cast
(int).- Why: Safe vs lossy ➔ Java auto-converts only when the larger type can hold every value of the smaller.
new String("test") == new String("test")isfalse, but.equals()istrue. Why?Answer
- Short answer:
==compares addresses;newforces two separate heap objects, so their addresses differ..equals()compares the character values, which are identical.- Why: Identity vs value ➔ literal strings are pooled (shared address, so
==istrue), butnewbypasses the pool — always use.equals()for string value comparison.