805 OCPJP 6 Questions 788 SCJP 5 questions 650 OCPJWCD 5 questions 600 OCAJP 7 questions 610 OCPJP 7 questions 510 Upgrade to OCPJP 7 questions 900 Java J2EE Qns

Tutorials

Upgrade to OCPJP 7 Java SE 7 Programmer (1Z0-805) Guide : Language Enhancements

SCJP 6/OCPJP Exam Kit

1) Language Enhancements

In Java SE 7 and later, you can use a String object in the switch statement's expression. The following code example, StringSwitch, displays the color RGB based on the value of the String named color:

public class StringSwitch {
    public static void main(String[] args) {
        String color = "black";
        switch (color) {
            case "white":
                System.out.print(color + " RGB: ffffff");
                break;
            case "black":
                System.out.print(color + " RGB: 000000");
                break;
            default:
                System.out.print(color + " RGB: UNKNOWN");
                break;
        }
    }
}
					

The output from this code is:

black RGB: 000000
					

The String in the switch expression is compared with the expressions associated with each case label as if the String.equals(...) method were being used. Two things to keep in mind:

  • Check for null before the switch:

    public class StringSwitchNull {
        public static void main(String[] args) {
            String color = null;
            switch (color) {
                case "white":
                    System.out.print(color + " RGB: ffffff");
                    break;
                case "black":
                    System.out.print(color + " RGB: 000000");
                    break;
                default:
                    System.out.print(color + " RGB: UNKNOWN");
                    break;
            }
        }
    }
    								

    result:

    Exception in thread "main" java.lang.NullPointerException
    	at c1.s1.StringSwitchNull.main(StringSwitchNull.java:9)
    Java Result: 1
    								

  • Check for different case letters before the switch:

    public class StringSwitchCase {
        public static void main(String[] args) {
            String color = "BlAcK";
            switch (color) {
                case "white":
                    System.out.print(color + " RGB: ffffff");
                    break;
                case "black":
                    System.out.print(color + " RGB: 000000");
                    break;
                default:
                    System.out.print(color + " RGB: UNKNOWN");
                    break;
            }
        }
    }
    								

    result:

    BlAcK RGB: UNKNOWN
    								




1.2. Use binary literals, numeric literals with underscores

Integer Literals

An integer literal is of type long if it ends with the letter 'L' or 'l'; otherwise it is of type int. It is recommended that you use the upper case letter 'L' because the lower case letter 'l' is hard to distinguish from the digit 1.

Values of the integral types byte, short, int, and long can be created from int literals. Values of type long that exceed the range of int can be created from long literals. Integer literals can be expressed these number systems:

  • Decimal: Base 10, whose digits consists of the numbers 0 through 9; this is the number system you use every day

  • Hexadecimal: Base 16, whose digits consist of the numbers 0 through 9 and the letters A through F

  • Binary: Base 2, whose digits consists of the numbers 0 and 1 (you can create binary literals in Java SE 7 and later)

For general-purpose programming, the decimal system is likely to be the only number system you will ever use. However, if you need to use another number system, the following example shows the correct syntax. The prefix '0x' indicates hexadecimal and '0b' indicates binary:

int decVal = 26;      // The number 26, in decimal
int hexVal = 0x1a;    // The number 26, in hexadecimal
int binVal = 0b11010; // The number 26, in binary
					

Binary Literals

In Java SE 7, the integral types (byte, short, int, and long) can also be expressed using the binary number system. To specify a binary literal, add the prefix 0b or 0B to the number. The following examples show binary literals:

// An 8-bit 'byte' value:
byte aByte = 0b00100001;

// A 16-bit 'short' value:
short aShort = 0b0010001010001010;

// Some 32-bit 'int' values:
int anInt1 = 0b10100001010001011010000101000101;
int anInt2 = 0b101;
int anInt3 = 0B101; // The B can be upper or lower case.

// A 64-bit 'long' value. Note the "L" suffix:
long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;

// OK, implicit casting int to float or double variable
float  f1 = 0b0001;
double d1 = 0b0001;

// COMPILATION FAILS! Binary literal can only be of integer type (byte, char, int, long),
// while 'd' or 'f' suffixes explicitly say these are decimal point type literals
double d2 = 0b0001d;
float  f2 = 0b0001f;
					

Underscores in Numeric Literals

In Java SE 7 and later, any number of underscore characters (_) can appear anywhere between digits in a numerical literal. This feature enables you, for example, to separate groups of digits in numeric literals, which can improve the readability of your code.

For instance, if your code contains numbers with many digits, you can use an underscore character to separate digits in groups of three, similar to how you would use a punctuation mark like a comma, or a space, as a separator.

The following example shows other ways you can use the underscore in numeric literals:

long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi = 3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;
					

You can place underscores only between digits; you CANNOT place underscores in the following places:

  • At the beginning or end of a number

  • Adjacent to a decimal point in a floating point literal

  • Prior to an 'F' or 'L' suffix

  • In positions where a string of digits is expected

The following examples demonstrate valid and invalid underscore placements in numeric literals.

Valid:

int x1 = 5_2;              // OK (decimal literal)
int x2 = 5_______2;        // OK (decimal literal)
int x3 = 0x5_2;            // OK (hexadecimal literal)
int x4 = 0B0_0_0;          // OK (binary literal)
					

Invalid:

float pi1 = 3_.1415F;       // Cannot put underscores adjacent to a decimal point
float pi2 = 3._1415F;       // Cannot put underscores adjacent to a decimal point
long ssn  = 999_99_9999_L;  // Cannot put underscores prior to an L suffix

int x1 = 52_;               // Cannot put underscores at the end of a literal
int x2 = 0_x52;             // Cannot put underscores in the 0x radix prefix
int x3 = 0x_52;             // Cannot put underscores at the beginning of a number
int x4 = 0x52_;             // Cannot put underscores at the end of a number
					

Invalid (compilable, but logical error):

int x1 = _52;              // This is an identifier, not a numeric literal
					




Use try-with-resources

The try-with-resources statement is a try statement that declares one or more resources.

A resource is as an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource:

package java.lang;

public interface AutoCloseable {
    void close() throws Exception;
}
					

The Closeable interface extends the AutoCloseable interface. The close() method of the Closeable interface throws exceptions of type IOException while the close() method of the AutoCloseable interface throws exceptions of type Exception. Consequently, subclasses of the AutoCloseable interface can override this behavior of the close() method to throw specialized exceptions, such as IOException, or no exception at all.

package java.io;

import java.io.IOException;

public interface Closeable extends AutoCloseable {
    public void close() throws IOException;
}
					

The following example reads the first line from a file. It uses an instance of BufferedReader to read data from the file. BufferedReader is a resource that must be closed after the program is finished with it:

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br = new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}
					

In this example, the resource declared in the try-with-resources statement is a BufferedReader. The declaration statement appears within parentheses immediately after the try keyword. The class BufferedReader, in Java SE 7 and later, implements the interface java.lang.AutoCloseable. Because the BufferedReader instance is declared in a try-with-resource statement, it will be closed regardless of whether the try statement completes normally or abruptly (as a result of the method BufferedReader.readLine throwing an IOException).

Prior to Java SE 7, you can use a finally block to ensure that a resource is closed regardless of whether the whether the try statement completes normally or abruptly. The following example uses a finally block instead of a try-with-resources statement:

static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        if (br != null) br.close();
    }
}
					

However, in this example, if the methods readLine and close both throw exceptions, then the method readFirstLineFromFileWithFinallyBlock throws the exception thrown from the finally block; the exception thrown from the try block is suppressed. In contrast, in the example readFirstLineFromFile, if exceptions are thrown from both the try block and the try-with-resources statement, then the method readFirstLineFromFile throws the exception thrown from the try block; the exception thrown from the try-with-resources block is suppressed. In Java SE 7 and later, you can retrieve suppressed exceptions; see the next section for more information.

You may declare one or more resources in a try-with-resources statement. The following example makes a copy of a file, using the try-with-resources statement. There are two resources defined in the try statement, separated by a semicolon, which are automatically closed when the statement completes:

public static void copyFile(String src, String dest) throws IOException  {
    try (BufferedReader in = new BufferedReader(new FileReader(src));
         BufferedWriter out = new BufferedWriter(new FileWriter(dest))) {
        String line;
        while((line = in.readLine()) != null) {
            out.write(line);
            out.write('\n');
        }
    } // No need to close resources in a "finally"
}
					

NOTE: the close() methods of resources are called in the OPPOSITE order of their creation.

NOTE: in try-with-resource statement the catch and the finally blocks are OPTIONAL.

In JDBC 4.1 the java.lang.AutoCloseable interface is extended by the following interfaces:

  • java.sql.Connection

  • java.sql.ResultSet

  • java.sql.Statement

The following example uses a try-with-resources statement to automatically close a java.sql.Statement object:

public static void viewTable(Connection con) throws SQLException {
    String query = "SELECT ... FROM ...";
    try (Statement stmt = con.createStatement()) {
        ResultSet rs = stmt.executeQuery(query);
        while (rs.next()) {
            // ...
        }
    } catch (SQLException e) {
        // ...
    }
}
					

The resource java.sql.Statement used in this example is part of the JDBC 4.1 and later API.

NOTE: A try-with-resources statement CAN have catch and finally blocks just like an ordinary try statement. In a try-with-resources statement, any catch or finally block is run AFTER the resources declared have been closed.

Making an Auto-Closeable Class

As you know, a try-with-resources statement cannot manage every class. A new interface called java.lang.AutoCloseable was introduced in Java SE 7. All it does is provide a void method named close() that may throw a checked exception (java.lang.Exception). Any class willing to participate in try-with-resources statements should implement this interface. It is strongly recommended that implementing classes and sub-interfaces declare a more precise exception type than java.lang.Exception, or, even better, declare no exception type at all if invoking close() should not fail.

Such close() methods have been retro-fitted into many classes of the standard Java SE run-time environment , including the java.io, java.nio, javax.crypto, java.security, java.util.zip, java.util.jar, javax.net, and java.sql packages. The major advantage of this approach is that existing code continues working just as before, while new code can easily take advantage of the try-with-resources statement.

Consider the following example:

public class AutoCloseableResource implements AutoCloseable {

    @Override
    public void close() {
        System.out.println("in close()");
        throw new RuntimeException("Exception in close()");
    }

    public void work() throws Exception {
        System.out.println("in work()");
        throw new Exception("Exception in work()");
    }
}
					

public class AutoCloseableTest {

    public static void main(String[] args) {
        try (AutoCloseableResource resource = new AutoCloseableResource()) {
            resource.work();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
					

The AutoCloseableResource class implements java.lang.AutoCloseable and can thus be used as part of a try-with-resources statement, as illustrated in the AutoCloseableTest.main(...) method. Intentionally, we added some console output, and we throw exceptions both in the work() and close() methods of the class. Running the program yields the following output:

in work()
in close()
java.lang.Exception: Exception in work()
	at AutoCloseableResource.work(AutoCloseableResource.java:21)
	at AutoCloseableTest.main(AutoCloseableTest.java:15)
	Suppressed: java.lang.RuntimeException: Exception in close()
		at AutoCloseableResource.close(AutoCloseableResource.java:16)
		at AutoCloseableTest.main(AutoCloseableTest.java:16)
					

The output clearly proves that close() was indeed called BEFORE entering the catch block that should handle the exception. Yet, the Java developer discovering Java SE 7 might be surprised to see the exception stack trace line prefixed by "Suppressed: ...". It matches the exception thrown by the close() method, but you could never encounter such a form of stack trace prior to Java SE 7.

Suppressed Exceptions

If both the (explicit) try block and the (implicit) resource handling code throw an exception, then the try block exception is the one which will be thrown. The resource handling exception will be made available via the Throwable.getSupressed() method of the thrown exception. The Throwable[] Throwable.getSupressed() is a new method added to the Throwable class since Java SE 7 specifically for this purpose. If there were no suppressed exceptions then this will return an empty array.

The Java SE 7 extensions to java.lang.Throwable are as follows:

  • public final void addSuppressed(Throwable exception) - appends a suppressed exception to another one, so as to avoid exception masking.

  • public final Throwable[] getSuppressed() - gets the suppressed exceptions that were added to an exception.

These extensions were introduced especially for supporting the try-with-resources statement and fixing exception-masking problems.

An exception can be thrown from the block of code associated with the try-with-resources statement. In the example copyFile above, an exception can be thrown from the try block, and up to two exceptions can be thrown from the try-with-resources statement when it tries to close the BufferedReader and BufferedWriter objects. If an exception is thrown from the try block and one or more exceptions are thrown from the try-with-resources statement, then those exceptions thrown from the try-with-resources statement are SUPPRESSED, and the exception thrown by the try block is the one that is thrown by the copyFile method. You can retrieve these suppressed exceptions by calling the Throwable.getSuppressed method from the exception thrown by the try block.




Use multi-catch in exception statements

In Java SE 7, a single catch block can handle more than one type of exception. This feature can reduce code duplication and lessen the temptation to catch an overly broad exception.

Consider the following example, which contains duplicate code in each of the catch blocks:

try {
    // ...
} catch (IOException ex) {
    logger.log(ex);
    throw ex;
} catch (SQLException ex) {
    logger.log(ex);
    throw ex;
}
					

In releases prior to Java SE 7, it is difficult to create a common method to eliminate the duplicated code because the variable ex has different types.

The following example, which is valid in Java SE 7, eliminates the duplicated code:

try {
    // ...
} catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}
					

The catch clause specifies the types of exceptions that the block can handle, and each exception type is separated with a vertical bar (|).

NOTE: An exception can not be a subtype or supertype of one of the catch clause's exception parameters, otherwise code will not compile:

try (DataOutputStream out = new DataOutputStream(new FileOutputStream("data"))) {
    out.writeUTF("Hello");
} catch (FileNotFoundException | IOException  e) { // COMPILATION FAILS !!!
    // ...
}
					

public class FileNotFoundException extends IOException {
    // ...
}
					

NOTE: If a catch block handles more than one exception type, then the catch parameter is implicitly final. In this example, the catch parameter ex is final and therefore you cannot assign any values to it within the catch block:

try (DataOutputStream out = new DataOutputStream(new FileOutputStream("data"))) {
    out.writeUTF("Hello");
} catch (RuntimeException | IOException  e) {
    e = new Exception(); // COMPILATION FAILS !!! (The e is final)
}
					

Bytecode generated by compiling a catch block that handles multiple exception types will be smaller (and thus superior) than compiling many catch blocks that handle only one exception type each. A catch block that handles multiple exception types creates no duplication in the bytecode generated by the compiler; the bytecode has no replication of exception handlers.



Use the diamond operator with generic declarations

You can replace the type arguments required to invoke the constructor of a generic class with an empty set of type parameters (<>) as long as the compiler can infer the type arguments from the context. This pair of angle brackets is informally called the diamond.

For example, consider the following variable declaration:


Map<String, List<String>> myMap = new HashMap<String, List<String>>();

					

In Java SE 7, you can substitute the parameterized type of the constructor with an empty set of type parameters (<>):


Map<String, List<String>> myMap = new HashMap<>();

					

Note that to take advantage of automatic type inference during generic class instantiation, you MUST specify the diamond. In the following example, the compiler generates an unchecked conversion warning because the HashMap() constructor refers to the HashMap raw type, not the Map<String, List<String>> type:


Map<String, List<String>> myMap = new HashMap(); // unchecked conversion warning

					

Java SE 7 supports limited type inference for generic instance creation; you can only use type inference if the parameterized type of the constructor is obvious from the context. For example, the following example DOES NOT compile:


List<String> list = new ArrayList<>();
list.add("A");

// The following statement should fail since addAll expects Collection<? extends String>

list.addAll(new ArrayList<>()); // Compilations fails !!!

					

Note that the diamond often works in method calls; however, it is suggested that you use the diamond primarily for variable declarations.

In comparison, the following example successfully compiles:


List<String> list = new ArrayList<>();
list.add("A");

List<? extends String> list2 = new ArrayList<>(); // NOT very practical ;-)
list.addAll(list2);                               // OK, it expects Collection<? extends String>

					

The compiler infers the type on the right side. So if you have a List of ?, the compiler will infer a list of Object:


List<?> list = new ArrayList<>();

					




Use more precise rethrow in exceptions

The Java SE 7 compiler performs more precise analysis of rethrown exceptions than earlier releases of Java SE. This enables you to specify more specific exception types in the throws clause of a method declaration.

Consider the following example:

public class FirstException extends Exception {
    // ...
}
					

public class SecondException extends Exception {
    // ...
}
					

public void rethrowException(String exceptionName) throws Exception {
    try {
        if (exceptionName.equals("First")) {
            throw new FirstException();
        } else {
            throw new SecondException();
        }
    } catch (Exception e) {
        throw e;
    }
}
					

This examples's try block could throw either FirstException or SecondException. Suppose you want to specify these exception types in the throws clause of the rethrowException method declaration. In releases prior to Java SE 7, you cannot do so. Because the exception parameter of the catch clause, e, is type Exception, and the catch block rethrows the exception parameter e, you can only specify the exception type Exception in the throws clause of the rethrowException method declaration.

However, in Java SE 7, you CAN specify the exception types FirstException and SecondException in the throws clause in the rethrowException method declaration. The Java SE 7 compiler can determine that the exception thrown by the statement throw e; must have come from the try block, and the only exceptions thrown by the try block can be FirstException and SecondException. Even though the exception parameter of the catch clause, e, is type Exception, the compiler can determine that it is an instance of either FirstException or SecondException:

public void rethrowException(String exceptionName) throws FirstException, SecondException {
    try {
        // ...
    } catch (Exception e) {
        throw e;
    }
}
					

This analysis is disabled if the catch parameter is assigned to another value in the catch block. However, if the catch parameter is assigned to another value, you must specify the exception type Exception in the throws clause of the method declaration.

In detail, in Java SE 7, when you declare one or more exception types in a catch clause, and rethrow the exception handled by this catch block, the compiler verifies that the type of the rethrown exception meets the following conditions:

  • The try block is able to throw it.

  • There are no other preceding catch blocks that can handle it.

  • It is a subtype or supertype of one of the catch clause's exception parameters.

The Java SE 7 compiler allows you to specify the exception types FirstException and SecondException in the throws clause in the rethrowException method declaration because you can rethrow an exception that is a supertype of any of the types declared in the throws.

In releases prior to Java SE 7, you cannot throw an exception that is a supertype of one of the catch clause's exception parameters. A compiler from a release prior to Java SE 7 generates the error, "unreported exception Exception; must be caught or declared to be thrown" at the statement throw e;. The compiler checks if the type of the exception thrown is assignable to any of the types declared in the throws clause of the rethrowException method declaration. However, the type of the catch parameter e is Exception, which is a supertype, not a subtype, of FirstException and SecondException.


  Upgrade to OCPJP 7 Java SE 7 Programmer (1Z0-805) Guide

  • Language Enhancements
  • Design Patterns
  • Describe the JDBC API
  • Concurrency
  • Localization
  • Java File I/O (NIO.2)


  • Mock Questions

      scwcd 1.5 mock questions

  • Servlet Basic
  • The Structure and Deployment of Web Applications
  • The Web Container Model
  • Servlet event listeners
  • Session Management,session listeners
  • Servlet Filter
  • Web Application Security
  • j2ee patterns
  • JSP Directives
  • JSP page life cycle
  • JSP implicit objects
  • JSP include
  • Expression Language (EL)
  • JSTL
  • Building a Custom Tag Library
  • scjp 1.5 | scjp 1.6 | scwcd 1.5
    Java Certifications
    www.javacertifications.net