SCJP – Language fundamentals

[[pageindex]]

Don't forget

  • to look to call to a non-static context from a static context. E.g. call from main to a non-static method. Or to refer from any static method to this.
  • to check the initialization of local variables that are used for reading. In particular in main method.
  • to check if variable are initialized, other way it will give NullPointException at runtime.
  • to check it there is any missing import.
  • on System.out.print(ga.i + " " + ga.getI()); first are executed each part and only after is printed
  • a cast of null is always ok. Don't forget to check the variable current value to see if it throw a ClassCastException
  • a cast of two type not in same hierarchy give compilation error.
  • to check unreachable code: after a throw, while (false), catch block.
  • ASCII table: 123 ABC abc

Notes

  • [static] [public] [final] <return type> <method name ! attribute name>
    • static public and final can change the order in between
  • args[0].equals() in the main method will throw an ArrayIndexOutOfBound, not a NullPointException
  • abstract methods ends with ; -- non abstracts methods must have body{}
  • Identifiers can't start with a digit or characters other than '_' or '$' or letters,
    • the remaining of the identifier can contain digits, letters, '_' or '$' but not other
  • oThe escape sequences are as follows: '\b' (backspace), '\f' (formfeed, new page), '\n' (newline), '\r' (carriage return), '\t' (horizontal tab), '\\' (backslash), st'\"' (double quote), '\'' (single quote). Yes, you must memorize the escape sequences! Just remember "big farms need red tractors".
  • Invalid escape sequence (valid ones are \b \t \n \f \r \" \' \\ )
  • A method cannot be abstract and final at same time. It's the opposite.
  • Immutable objects are simply objects whose state (the object's data) cannot change after construction.
  • final classes cannot be sub classed
  • If a class is not final cannot be immutable.
  • Class1 HAS A Class2- could be indirectly by Class1 HAS A Class3 that HAS A Class2

Java Keywords

  • const
  • goto
  • instanceof - not "instance of" or instanceOf

JavaBeans

  • getters and setters must be public
  • must be named using camelCase
  • depending on the method's purpose, must start with set, get, is, add, or remove.

Constructors

  • It's possible to have a method with the same name as the constructor/class: protected void Foo() { }
  • Only public, protected, private and default (no modifier) are legal when declaring constructors
  • Foo extends Bar.
    • If Bar have a default constructor, no issues in the Foo constructor: no need no call super in the non-default constructors.
    • If Bar have only non-default constructors, the Foo have to call super(...) to invoke the parent non-default constructor
  • If you've typed in a constructor with arguments, you won't have a no-arg constructor unless you type it in yourself!
  • Every constructor has, as its first statement, either a call to an overloaded constructor (this()) or a call to the superclass constructor (super()), although remember that this call can be inserted by the compiler.
    • the call to super cannot be inside a try catch block. It must be really the first statement of the constructor.
  • The no-argument constructor provided by the compiler when no constructor is explicitly provided in the code always defaults to the access modifier provided for the class
  • No constructor calls are allowed inside a method. A constructor call (super() or this() ) must be the first statement inside a constructor.
  • Constructors can throw exception as any other method.
  • If the Super class provides a constructor that throws a checked exception, then the sub classes must define an explicit constructor that also throws the same exception or one of its super types
    • This because the all constructors (explicit or implicit) have a call to the super constructor. The super() call (explicit or implicit) must be the first line and so it's not allowed even the try/catch o catch a non handle exception thrown by the super constructor.
  • The parent class constructor must be visible: With a private constructor, the Child will give compilation error.

Initializations, Static and init blocks

  • if you try to use local variables without initialization it give compilation error.
    • if is a instance variable without initialization doesn't give compilation error, because some other method can change it.
  • final instance variable must be initialized: immediately, in all constructors or in a initialisation block.
  • variable can be initializaed using a method call. (Issue with usual static calls rules)

Initiatization order

  • Static variables/static blocks are executed, run once, when the class is first loaded.
    • first the blocks from the super class
    • file order if more than one: if a block appears first then a static variable it's initialized first
  • Instance variables are assigned default values
  • constructor runs
    • instance variables and Instance initialization blocksrun after all super-constructors and before the constructor's code has run.
      • If multiple init blocks exist in a class, they run in the order in which they appear in the source file.
    • rest of the constructor is executed

 

  • Doesn't compile if we try to use in a subclass explicit call to super(variable) a instance variable defined on the super class because the instance hasn’t been created yet.
  • If the super constructor call a method that is overriden in a subclass it works and the polymorphism works also
    • If the instance variable are not initialized yet, the default values are used
  • if a class with no main is called, it will fail with NoSuchMethodError, but it will first execute the static init block.
  • static int[] a;
    static {
    a[0] = 5;
    }
  • This wil throw a java.lang.ExceptionInInitializerError (caused by a NullPointException), because static block is trying to access to a null object: note that array a is not initialized.
    • If the assign was in a non-static init block, or in a constructor or in the main, the result was simply the NullPointException

Interfaces

  • Interface methods are implicitly public, and abstract
    • so the methods being implemented must also marked be public.
  • Interface attributes are implicitly public, static, and final : interface constants.
    • as they are final, must always be initialized on the declaration
  • No others modifiers are allowed: It's not possible to have methods protected or private
    • It's not possible to have methods static or final
  • It's allowed to declare inner classes inside a interface
  • Interface extends another interface: both can have the same method (same name) defined. And a class can implement both interfaces, and of course need to implement one only method.

Finalize and GC

  • For any given object, finalize() will be called only once (at most) by the garbage collector.
  • finalize() method ignores the throw of a runtime exception inside of it.
  • If finalize assigns the this reference to other object, it cannot be garbage collected.
    • But at second change to GC runs, it will be garbage collected anyway.
  • new Fiji().go(); //on the line bellow this object is eligible for GC
  • reference variables live on the heap
  • stack variables are not GC. they are removed when the method exists.
  • WRONG: only objects that have no reference variables can be GC. No because the islands of objects can also be GC.

Serialization

  • transient - if a variable (instance only) is marked as transient it will not be serialised
    • When the object is rebuild (via readObject), the value is the default, not the previous neither the initialized value.
      • transient int a = 5; After readObject is will be 0.
  • volatile - for instance variables only, not is exam, is not related with serialization, is related with thread-safe.
    • value is not lost during the serialization
  • The order of writing/reading fields must be the same.
  • Class fields with the modifiers static and transient will not be serialized.
  • if a superclass is not marked Serializable the data is not saved and then on rebuild the constructor is invoked
  • If a class member is not Serializable, it will skip it. No compiler error.
try {
   FileOutputStream fos = new FileOutputStream("data.txt");
   ObjectOutputStream os = new ObjectOutputStream(fos);
   os.writeObject(derived1);
   os.close();
   FileInputStream fis = new FileInputStream("data.txt");
   ObjectInputStream is = new ObjectInputStream(fis);
   Derived derived2 = (Derived) is.readObject();
   System.out.print(derived2.code);
   is.close();
} catch (Exception x) {
}

Modifiers

  • Visibility modifiers order:
    • private
    • default (package)
    • protected - this also includes package
    • public
  • outer classes could be public or abstract, or default
  • inner classes could be public, protected, private or default, as any other class member
  • abstract interface == interface
  • strictfp applies to classes, interfaces and methods
  • An abstract method cannot be marked static.
  • An abstract method can be marked protected
  • Local variables cannot have access modifiers: cannot be protected or private
  • If a method is private, the subclass can define it again, but in this case is not a override.
    • Any method call using the type reference to the super, will call the super method, the polymorphism doesn't work because isn't a override
    • The private method in the super can be final, and even that could be defined again in the subclass, because it's not visible.
  • Don't forget to see if a method is public to be access from the outside the class (different packages), even is called on a instance of the same type.
    • Same package is ok in most of the cases
  • u.do1() - to check if the visibility of the do1() allows this call, must be checked also the u object
    • if do1() is protected and in another package, in a subclass if u is the superclass it's not visible

Exceptions

  • Throwable is a class, not an interface
  • RuntimeException extends Exception extends Throwable
    • Of course a catch(Exception e) will catch also RuntimeExceptions
  • Error extends Throwable
    • so AssertionError is not catch in the catch by Exception
    • Error is a (and RuntimeException) unchecked exception
  • When there are multiple catch block, the most specific exception is caught (in the case of subclasses)
  • Pay attention to Unreachable catch block on try catch statements: if a catch that appears first catch the exception bellow, it's a unreachable block
  • finally block runs before the exception in the try block is thrown
  • protected void finalize() throws Throwable { } - is the signature of the finalize method on Object

List of Runtime Exceptions

  • ArithmeticException
  • IllegalMonitorStateException
  • IllegalThreadStateException
  • NumberFormatException extends IllegalArgumentException
  • IllegalStateException
  • IllegalArgumentException
  • almost all IllegalXXX are runtime exceptions

List of checked Exceptions

  • InterruptedException
  • ClassNotFoundException
  • ParseException

Strings

  • Any operation with strings (substring, upperCase, replace, ...) if returns the same content, it returns the same object: this.
  • Strings starts and ends with "" (empty string)
  • String are kept in a string pool, managed and limited by JVM
  • Numbers (int short, long) also have a pool until 127

Override

  • The method definition is name + arguments.
  • To override a method is must have the same name+arguments (Same type, not a subtype). Otherwise it will be an overloaded method.
  • applies ONLY to inherited methods
  • is related to polymorphism
  • object type (NOT reference variable type) determines which overridden method will be used at runtime
  • overriding method MUST have the same return type;
  • exceptions rules:
      • it must throw the same exception declared in the super class, or
      • it must throw one sub-class of the one declared in the super class, or
      • throw nothing, or
      • throw RuntimeException (unchecked exceptions)
    • this rules also are applied to interfaces
    • The existing code, prepared to catch some exception, must be valid if we override a method, and so the exception thrown must be equal or less than original (subclass or nothing)
  • overriding method MUST NOT have more restrictive access modifier, but MAYhave less restrictive one
    • the same to implement interface methods: it's a override !!
    • due to other code that calls the method, that can invoke on a polymorphic instance
  • abstract methods MUST be overridden
  • final methods CANNOT be overridden
  • static methods CANNOTbe overridden
    • but must follow all rules for overriden method, but of course that polymorphism doesn't exists.
    • even cannot be defined a non-static method with same signature in a subclass.
  • constructors CANNOT be overridden
  • declare a override method with <T> don't compile
  • method declaration with byte, short, int or char are all different, not an override.

Overload

  • if the method name + arguments are the same then it's a override and should follow the override rules
  • reference type determines which overloaded method will be used
    • the method that will be used it chosen at compile time
  • match always the most specific object. someMethod(Object o) and someMethod(String s), called with null as arg it choose String.
  • calling methods with null arg only fails with ambiguous case, when there is two overloaded methods with different args that one IS NOT the another one (IS in sense to hierarchy)
  • overloading can take place in the same class or in the subclass
  • overloaded methods MUST have a different argument list
  • overloaded methods MAY change the return type (in case argument list is different)
  • overloaded methods MAY change the access modifier
  • overloaded methods MAY throw new or broader checked excpetions
  • constructors MAY be overloaded
  • you cannot have a static method and a non-static method with the same signature
  • methods adjustment in connection with overloaded method’s arguments:
    • you cannot widen and then box (int -> Long)
    • you can box and then widen (int -> Object, via Integer)
    • you cancombine var args with either widening (byte -> int) or boxing (int -> Integer):
      • widening is over boxing
      • widening is over var args
      • boxing is over var args
  • As method arguments: String[] and String... are the same type, and then it's a duplicate
    • List<String> and String... are different types
  • You can pass values or an array to a vararg method, but not both. Ex: rest(1,{2}) rest(int ... a) //compile error
  • With tMeth(Integer... i) and tMeth(int... i) methods a call like tMeth(7) will give compilation error
    • the error in that the call is ambiguous. The error is on the call.
    • If we and a third method tMeth(int i), of course is not ambiguos anymore
  • Reference type determines which overloaded method is used at compile time.
  • Object type determines which overriden method is used at runtime.

 

Operators

  • i++ vs ++i :
    • in a for loop, the 3rd block is only compute at the end, so no matter if it's i++ or ++i
    • in a comparison ++i is evaluated first

Static

  • static variables are not serialized. They belong to the class, not to an instance.
    • The static variables current value is not kept, the value will revert to the init value.
  • Static methods can be called using an instance. Even if the instance is null.
    • It will call the method based on the object type, not object instance
  • It's not possible to have two methods with same signature, one static and another non-static.
  • A class has two methods: static void print(Integer arg) and void print(int arg)
    • To call from a (non-static block) or (in a static block but using an instance reference), only the rules for overload with boxing applies

Polymorphism

  • polymorphism to access class variables doesn't work. A classic example to show polymorphism in methods doesn't work.
  • if a instance attribute is defined both in parent and a child classes, and parent method is executed on a child instance it reads the parent attribute
  • super.aMethod - calls exactly the super method, no polymorphism here
    • this.AMethod is the same but for this
  • g.super.aMethod - compilation error
  • super.super.aMethod - compilation error

Switch

  • Switch without no break statement proceeds to the next case, even if the case doesn't match.
  • Switch only works with integer convertible (int, short, byte, char) or with enum (even with a enum literal: is a enum anyway)
    • with a enum in the switch selector, the cases could be only the values (without qualification of the enum name)
    • it's not allowed box/unbox: doesn't work with final Integer in the case instead of int
  • default don't need to be the last statement after all the cases

If Else

  • Chained "if else" statements without brackets works fine, no compilation error for ambiguous code.

For loop

for (initialization; termination; increment) {
    statement(s)
}
  • The initialization expression initializes the loop; it's executed once, as the loop begins.
  • When the termination expression evaluates to false, the loop terminates.
  • The increment expression is invoked after each iteration through the loop; it is perfectly acceptable for this expression to increment or decrement a value.
  • for(int i = 0; i<10; i++){} is the same as for(int i = 0; i<10; ++i){

Coupling, cohesion and encapsulation

Tips to check those concepts over a code snippet.

Encapsulation

  • well-encapsulated code is that methods can be re-implemented without causing side effects
  • Getters and setters are the requirement for encapsulation
    • It's not related with coupling or cohesion

Coupling

  • Loosely coupled - if there is few interface calls
  • loose coupling is when one class can change without adversely affecting the workings of classes that interact
    with it.
  • A is-a class B, or A has-a class B --- it’s possible for them to still be loosely coupled

Cohesion

  • Somewhat subjective, but look to the class where where should be placed the methods

 

Arrays

  • short [] z [][]; // It's a coorect declaration of t 3-dimension array!
  • A[] a=new C[1]{ new Test(), new D() };
    • This array, C , can accept all object that pass the IS a C
    • The reference types are A
  • A[] a=new C[1]; a[0] = new A(); (C extends A)
    • compiles Ok
    • java.lang.ArrayStoreException at runtime -
    • array instances knows their type at runtime, in opposite to the generic collection

Not related

  • Equals method defined in jre classes first check if the classes are the same! Also is they are ==
  • public int compare(T o)
  • return statement in main exits but still runs the finally. System.exit(0) exits immediately.
  • "extends" comes before "implements"
  • s.concat() will produce a new String object and will not modify the original. Strings are immutable
  • TIP: Which methods are defined for both type String and type StringBuffer?
    • equals is a correct answer, despite it is defined only in Object object and String equals is defined on String object.
  • pay attention to the unreachable code
    • while (false){unreachable code} // compilation error
    • if (false){dead code} // warning, no compilation error

Instanceof

  • instanceof with null returns false, not a NullPointExecption
    • null instanceof Number --> compiles and returns false
  • Operands of instanceof must be in the same inheritance tree. Other way it give compilation error. Only if type is a class
    • variable instanceof Type. If Type is a interface: compilation ok. Because some instance that the variable can hold, in for instance is a subclass, can implement the interface. So, this is only possible to know at runtime.

 

Labels

  • Labels must be just before a loop
  • break exits only the most inner loop
  • break <label> exists from the loop with label
  • label: statement --- 'break label' or 'continue label' must be inside the labeled statement.
    • This means that if the label is not immediately before the loop, it will not be found when referenced by the break or continue.

Assertions

  • assert(exp) - will throw an exception if exp is false
  • In a question with assert code, don't forget to check if the assertions are enabled at runtime (java -ea), other way they are ignored
  • Run old code with assert as a variable name, not yet as keyword (Java 1.3)
    • javac -source 1.3 OldCode.java
  • Enable assertions at runtime:
    • java -ea com.geeksanonymous.TestClass
    • java -enableassertions com.geeksanonymous.TestClass
    • java -ea:com.foo.Bar com.geeksanonymous.TestClass
    • java -ea -da:com.foo...
    • java -ea -dsa Enable assertions in general, but disable assertions in system classes.
  • assertion is not appropriate if: (Assert should test invariants)
    • it is testing the args of main.
    • it is testing args of public methods
    • if they change variables state

Java, Javac and jar command line

  • java -cp t.jar Test.java
  • java -classpath /home/t.jar Test
    • if we need also to run a file in the current folder we need to add the . to the classpath (only if the classpath is explicitly indicated at command line)
    • this only yo run, doesn't apply to javac

Javac

  • By default, the compiler puts a .class file in the same directory as the .java
  • -d option lets you tell the compiler in which directory to put the .class files it generates
    • javac -d classes source/MyClass.java
    • if the destination directory you specify doesn't exist, you'll get a compiler error.

Java

  • java [options] class [args]
    • java PirateTalk -DargProp="dog," // the property is ignored, must come before the class name
  • java -DmyProp=myValue MyClass x 1
    • To read the properties in java code:
      • Properties p = System.getProperties(); p.getProperty("myProp");
    • whitespaces between "" - java -DcmdProp="cmdVal take 2" TestProps

Classpath search (both for java and javac)

  • As soon as they find the class they're looking for, they stop searching for that class.
  • Search order:
    • J2SE lib folders
    • directories defined by classpaths
      • command line classpath
      • system classpath

Jar

  • jar -cf MyJar.jar myApp

Main Java packages

  • java.lang
    • 'primitive objects', String, StringBuilder, StringBuffer, Thread, main execptions and errors, Comparable
  • java.text
    • DateFormat, NumberFormat
  • java.util
    • all collections and maps interfaces and classes, related exceptions, Date, Claendar, Locale, Scanner, Comparator
  • java.util.regex
    • Matcher, Pattern
  • java.io
    • File, Stream, Writers and Reader, related exceptions, console

Imports

  • import static <package+className>.*
    • imports all static methods, constants (which are static and final), and static object references. And can be used only by name.
    • static import don't compile.

Tags: ,

Leave a Reply