Thursday, August 21, 2014

Implied Behavior In Java

For the most part anything you want to do in Java has to be explicitly stated. Want to declare a variable? You have to give it a type. Want to use a particular class that's not in the same package? You have to import it. There are a few instances, however, where you don't have to be that explicit with your intention. The following are a few instances that I came up with. If there are any others that I have I missed please let me know.
The Object Superclass
Every class you write extends from the Object class. To put it another way, every class you write is a subclass of the Object class.
public class Klass {
   public static void main(String[] args) {
      System.out.println(new Klass() instanceof Object); // true
   }
}
Notice that even though this class doesn't explicitly extend from any other class it's still considered an instance of the Object class.

Reference
Java Programming : Advanced Topics (first edition) by Joe wigglesworth and Paula McMillan, page 116
PrintStream and Objects
The PrintStream class has two print methods that take in an object parameter:
  • public void print(Object obj)
  • public void println(Object obj)
Whenever you call either of these methods, PrintStream will use the object's toString( ) method to print it. It does this by calling String's valueOf(Object obj) method which then calls the object's toString( ) method.

So what this mean is – say, for example, you wanted to output an object to the console – you don't have to call the object's toString method. Java does that for you.

Both of these statements are equivalent:
System.out.println(obj); System.out.println(obj.toString( ));

Reference
The API for PrintStream class
The java.lang.* package
Every Java application implicitly imports the java.lang.* package. That's why when you use a String in your application you don't have to import the class. It's already been imported.

Reference
Java Programming : Advanced Topics (first edition) by Joe wigglesworth and Paula McMillan, page 181
Package Access Modifier
Any time you declare a class, method, field, or interface and you neglect to specify an access modifier like public or private; Java will automatically assign it the default package access.

I recently did a post on the scope of access modifiers and the following table was the result:

public protected (no modifier) private
Subclass, Same Package x x x
Non-Subclass, Same Package x x x
Subclass, Different Package x x
Non-Subclass, Different Package x

So, for example, if you wanted to limit the classes that can implement an interface, just don't specify an access modifier.
package Earth;

interface Earthling {
   void breath();
}
package Earth;

public class Man implements Earthling {

   @Override
   public void breath() {
      System.out.println("Ah! I can breath.");
   }
}
package Mars;

import Earth.Earthling; // Compiler Error
// 'Earth.Earthling' is not public in 'Earth'.  Cannot be accessed from outside package.

public class Martian implements Earthling {

   @Override
   public void breath() {
      System.out.println("I can't breath!");
   }
}
In Java you're restricted to one public class per java file. However if you leave off the public access modifier you are allowed to have multiple classes in a Java file. You don't even have to give any of the classes the same name as the java file.
// FooBar.java
class First {
}

class Second {
}

class Third {
}

Reference
Java Programming : Advanced Topics (first edition) by Joe wigglesworth and Paula McMillan, pages 151-154, 179, 209
Default Values for Fields
You can assign an initial value to instance variables in a class if you want to, but Java will give them a default value if you don't.
public class Klass {

   public int x;

   public static void main(String[] args) {
      System.out.println("x = " + new Klass().x); // x = 0
   }
}

The following table contains the default values for Java's primitive types. It was taken from The Java Tutorials : Primitive Data Types:

Primitive Type Default Value
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
char '\u0000'
boolean false

Also check out the post I did on "Java's Primitive Data Types."

Reference
Java Programming : Advanced Topics (first edition) by Joe wigglesworth and Paula McMillan, page 155
Subclasses Implicitly Call Their Parent's Default Constructor
Java always calls the Parent's default constructor when instantiating a Child class.
public class Parent {

   public Parent() {
      System.out.println("Parent's default constructor");
   }
}
public class Child extends Parent {

   public Child() {
      System.out.println("Child's default constructor");
   }
}
When a new Child object is instantiated, Java will output the following...
Parent's default constructor
Child's default constructor
Note: If the Parent class doesn't have a default (no parameter) constructor, then you must use the super keyword to explicitly call one of its constructors. Otherwise you'll get a compiler error.

Also check out the post I did on "Java's super and this keyword"

Reference
Java Programming : Advanced Topics (first edition) by Joe wigglesworth and Paula McMillan, page 218
Autoboxing and Unboxing
Whenever Java is given a primitive type where its object equivalent is expected, Java will automatically convert that primitive into an instance of the object. This is called autoboxing.
Boolean isThisAutoboxed = true;
Unboxing occurs when Java encounters an object where a primitive value is expected.
boolean isThisUnboxed = new Boolean(true);

Reference
The Java Tutorials: Autoboxing and Unboxing
Interface Methods Are Abstract
Whenever you want to force a developer to implement a specific method, you declare that method as being abstract. Although this is typically seen in abstract classes, interface methods can be declared abstract as well.
public interface MyInterface {
   public abstract void myMethod();
}
Since you're already forced to implement all the methods in an interface, they are implicitly declared as being abstract.
public interface MyInterface {
   public void myMethod();
}

Reference
Java Programming : Advanced Topics (first edition) by Joe wigglesworth and Paula McMillan, page 209
Interface Fields Are Static And Final
Since only static final fields are allowed in interfaces, the following...
public interface MyInterface {
   static final String str = "Hello World";
}
...is the same as...
public interface MyInterface {
   String str = "Hello World";
}
Check out the post I did on Java's static Keyword.
Reference
Java Programming : Advanced Topics (first edition) by Joe wigglesworth and Paula McMillan, page 209
Parameters Used In Multi-Catch Statement Are Final
When a catch block handles more than one exception, the parameter used in the catch block is implicitly made final. What that means is you cannot change the parameter variable to point to a different Exception object.
try {
   throw new NullPointerException();
}
catch(NullPointerException nullPointer) {
 nullPointer = new NullPointerException();
}

try {
   throw new NullPointerException();
}
catch(NullPointerException | IllegalArgumentException exception) {
   exception = new Exception(); // Compiler Error
}
Check out the post I did on Exception Handling in Java.
References
Oracle's article titled "Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking"
Enums
All enums implicitly extend from the java.lang.Enum class.
public enum Suit {
   HEARTS, DIAMONDS, SPADES, CLUBS;
}

System.out.println(Suit.HEARTS instanceof Enum); // true
Enums also implicitly implement java.io.Serializable and java.lang.Comparable.
System.out.println(Suit.HEARTS instanceof java.io.Serializable); // true
System.out.println(Suit.SPADES instanceof Comparable); // true
Check out the post I did on Enums in Java.
References
Javin Paul blog post titled "Java Enum Tutorial: 10 Examples of Enum in Java", which was posted on Saturday, August 13, 2011.

No comments:

Post a Comment