Java Notes - 1 (Thinking In Java)
- You treat (almost) everything as an object, using a single consistent syntax. Although you treat everyting as an object, the identifier you manipulate is actually a reference to an object.
- Just because you have a reference doesn’t mean there’s necessarily an object connected to it. Take this example:
String s;
But in this situation, if you decided to send a message to s (the reference), you’d get a compile time error. If your main class contains the following code:
String s;
char c = s.charAt(0);
The compiler would give this error:
variable s might not have been initialized
Because here, s isn’t actually attached to anything. A safer practice, then, is to initialize a reference when you create it:
String s = "qwerty";
- Strings have a special feature that they can be initialized with quoted text, as seen previously. Normally, you must use a more general type of initialization for objects.
- Primitive types are stored on the stack (as in C and C++) whereas objects are stored on the heap.
- All numeric types are signed, so don’t look for unsigned types.
- The wrapper classes for the primitive types allow you make a non-primitive object on the heap to represent that primitive type. For example:
Character ch = 'x';
Here, Character is the wrapper class for char and Java uses autoboxing that automatically converts from a primitive type to a wrapper type.
- BigInteger and BigDecimal classes are to be used for performaing high-precision arithmetic. BigInteger supports arbitrary-precision integers. This means that you can accurately represent integral values of any size without losing any information during operations. BigDecimal is for arbitrary-precision fixed-point numbers.
- Arrays are guaranteed to be initialized and cannot be accessed outside of their ranges (the primary goal of Java is safety). The compiler guarantees initialization of arrays of primitives because it zeroes the memory for that array. For example:
int[] onur = new int[2];
System.out.println(onur[0]);
The output for this code snippet would be:
0
- When you create an array of objects, you are really creating an array of references, and each of those references is automatically initialized to a special value with its own keyword: null. If you try to use a reference that’s still null, the problem will be reported at run time. Take this as an example:
String[] onur = new String[2];
char c = onur[0].charAt(0);
The compiler won’t throw an error during compilation; but the Java interpreter will throw an exception as follows:
Exception in thread “main” java.lang.NullPointerException at …
- A variable defined within a scope is available only to the end of that scope.
- Hiding a variable in a larger scope is not allowed; thus the following is illegal:
public static void main(String[] args) {
int x = 100;
{
int x = 105;
}
}
If you try to do that, you’ll get a compile time error announcing that the variable x has already been defined, as follows:
… x is already defined in main(java.lang.String[])
…
- When a primitive data type is a member of a class, it is guaranteed to get a default value if you do not initialize it. This ensures that member variables of primitive types will always be initialized. For example:
class Hede {
private int x;
public static void main(String[] args) {
Hede onur = new Hede();
onur.init();
}
public void init() {
System.out.println(x);
}
}
The output of this code snippet would be:
0
This guarantee doesn’t apply to local variables-those that are not fields of a class (as previously shown). Another example for this situation is as follows:
class Hede {
public static void main(String[] args) {
Hede onur = new Hede();
onur.init();
}
public void init() {
int y;
System.out.println(y);
}
}
This time, we get an error at compile time as:
Hede.java:9: variable y might not have been initialized
…
- The method name and argument list is called the signature of the method and it uniquely identifies that method.
- If you try to call the wrong method for an object, you’ll get an error message at compile time as follows:
String onur = "Onur";
onur.hede();
The compile time error is:
…: cannot find symbol
symbol: method hede()
location: class java.lang.String
…
- The type of the return value must be compatible with the type of the variable that the return value will be assigned to.
- A method definition must be placed withing a class definition for it to be compiled. For example:
class Hede {
}
public void hede() {
}
This time the compile time error is:
Hede.java:4: class, interface, or enum expected
…
- When the return type is void, then the return keyword is used only to exit the method, and is therefore unnecessary when you reach the end of the method.
- You can return from a method at any point; but if you’re given a non-void return type, then the compiler will force you (with error message) to return the appropriate type of value regardless of where you return. For example:
public int init() {
if (true) {
return;
}
return 1;
}
This time the compiler gives the following error:
… missing return value
…
- Just like the previous note; if you’ve defined a method whose return type is void (meaning that it won’t actually return a value) and you’re trying to return some value, the compiler will give an error. For instance:
public void init() {
return 1;
}
The compile time error will be:
… cannot return a value from method whose result type is void
…
But, this will work as expected:
public void init() {
return;
}