Skip to content

Instantly share code, notes, and snippets.

@RajaniCode
Last active June 5, 2024 15:06
Show Gist options
  • Select an option

  • Save RajaniCode/fd709766bc5acbf6644164f370177dee to your computer and use it in GitHub Desktop.

Select an option

Save RajaniCode/fd709766bc5acbf6644164f370177dee to your computer and use it in GitHub Desktop.
Java7.java
// Java 7
// JDK 7 // % java -version
// % export PATH="/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home/bin//":$PATH
// % zip "Archive.zip" *
// % javac Java7.java
// % javac Java7.java -Xlint:unchecked
// % java Java7
// Java 7
/*
1. Binary Literals
2. Strings in switch Statements
3. The try-with-resources Statement
4. Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking
5. Underscores in Numeric Literals
6. Type Inference for Generic Instance Creation
7. Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods
*/
import java.lang.System;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
class BinaryLiterals {
// 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 = (byte)0b00100001;
// A 16-bit 'short' value:
short aShort = (short)0b1010000101000101;
// 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;
// Binary literals can make relationships among data more apparent than they would be in hexadecimal or octal.
// For example, each successive number in the following array is rotated by one bit:
public static final int[] phasesAlpha = {
0b00110001,
0b01100010,
0b11000100,
0b10001001,
0b00010011,
0b00100110,
0b01001100,
0b10011000
};
// In hexadecimal, the relationship among the numbers is not readily apparent:
public static final int[] phasesBeta = {
0x31, 0x62, 0xC4, 0x89, 0x13, 0x26, 0x4C, 0x98
};
// You can use binary integral constants in code that you can verify against a specifications document, such as a simulator for a hypothetical 8-bit microprocessor:
private State decodeInstruction(int instruction, State state) {
if ((instruction & 0b11100000) == 0b00000000) {
final int register = instruction & 0b00001111;
switch (instruction & 0b11110000) {
case 0b00000000: return state.nop();
case 0b00010000: return state.copyAccumTo(register);
case 0b00100000: return state.addToAccum(register);
case 0b00110000: return state.subFromAccum(register);
case 0b01000000: return state.multiplyAccumBy(register);
case 0b01010000: return state.divideAccumBy(register);
case 0b01100000: return state.setAccumFrom(register);
case 0b01110000: return state.returnFromCall();
default: throw new IllegalArgumentException();
}
}
else {
final int address = instruction & 0b00011111;
switch (instruction & 0b11100000) {
case 0b00100000: return state.jumpTo(address);
case 0b01000000: return state.jumpIfAccumZeroTo(address);
case 0b10000000: return state.jumpIfAccumNonzeroTo(address);
case 0b01100000: return state.setAccumFromMemory(address);
case 0b10100000: return state.writeAccumToMemory(address);
case 0b11000000: return state.callTo(address);
default: throw new IllegalArgumentException();
}
}
}
// You can use binary literals to make a bitmap more readable:
private static final short[] HAPPY_FACE = {
(short)0b0000011111100000,
(short)0b0000100000010000,
(short)0b0001000000001000,
(short)0b0010000000000100,
(short)0b0100000000000010,
(short)0b1000011001100001,
(short)0b1000011001100001,
(short)0b1000000000000001,
(short)0b1000000000000001,
(short)0b1001000000001001,
(short)0b1000100000010001,
(short)0b0100011111100010,
(short)0b0010000000000100,
(short)0b0001000000001000,
(short)0b0000100000010000,
(short)0b0000011111100000
};
public void print() {
System.out.println("1. Binary Literals");
System.out.println(String.format("An 8-bit 'byte': %d", aByte));
System.out.println(String.format("A 16-bit 'short' value: %d", aShort));
System.out.println(String.format("Some 32-bit 'int' values: %d, %d, %d", anInt1, anInt2, anInt3));
System.out.println(String.format("A 64-bit 'long' value: %d", aLong));
System.out.println("Binary literals can make relationships among data more apparent than they would be in hexadecimal or octal");
for(int i = 0; i < phasesAlpha.length; i++) {
if (i < phasesAlpha.length - 1) {
System.out.printf("%d, ", phasesAlpha[i]);
} else {
System.out.printf("%d", phasesAlpha[i]);
}
}
System.out.println();
System.out.println("In hexadecimal, the relationship among the numbers is not readily apparent");
for(int i = 0; i < phasesBeta.length; i++) {
if (i < phasesBeta.length - 1) {
System.out.printf("%d, ", phasesBeta[i]);
} else {
System.out.printf("%d", phasesBeta[i]);
}
}
System.out.println();
System.out.println("You can use binary integral constants in code that you can verify against a specifications document, such as a simulator for a hypothetical 8-bit microprocessor");
System.out.println(decodeInstruction(Integer.MIN_VALUE, new State()).Code);
// java.lang.IllegalArgumentException
// System.out.println(decodeInstruction(Integer.MAX_VALUE, new State()).Code);
System.out.println("You can use binary literals to make a bitmap more readable");
for(int i = 0; i < HAPPY_FACE.length; i++) {
if (i < HAPPY_FACE.length - 1) {
System.out.printf("%d, ", HAPPY_FACE[i]);
} else {
System.out.printf("%d", HAPPY_FACE[i]);
}
}
System.out.println();
}
}
class State {
public String Code = "Decoded";
public State nop() {
return this;
}
public State copyAccumTo(int register) {
return this;
}
public State addToAccum(int register) {
return this;
}
public State subFromAccum(int register) {
return this;
}
public State multiplyAccumBy(int register) {
return this;
}
public State divideAccumBy(int register) {
return this;
}
public State setAccumFrom(int register) {
return this;
}
public State returnFromCall() {
return this;
}
public State jumpTo(int address) {
return this;
}
public State jumpIfAccumZeroTo(int address) {
return this;
}
public State jumpIfAccumNonzeroTo(int address) {
return this;
}
public State setAccumFromMemory(int address) {
return this;
}
public State writeAccumToMemory(int address) {
return this;
}
public State callTo(int address) {
return this;
}
}
class StringsInSwitchStatements {
// In the JDK 7 release, you can use a String object in the expression of a switch statement:
private String getTypeOfDayWithSwitchStatement(String dayOfWeekArg) {
String typeOfDay;
switch (dayOfWeekArg) {
case "Monday":
typeOfDay = "Start of work week";
break;
case "Tuesday":
case "Wednesday":
case "Thursday":
typeOfDay = "Midweek";
break;
case "Friday":
typeOfDay = "End of work week";
break;
case "Saturday":
case "Sunday":
typeOfDay = "Weekend";
break;
default:
throw new IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg);
}
return typeOfDay;
}
// The switch statement compares the String object in its expression with the expressions associated with each case label as if it were using the String.equals method; consequently, the comparison of String objects in switch statements is case sensitive.
// The Java compiler generates generally more efficient bytecode from switch statements that use String objects than from chained if-then-else statements.
public void print() {
System.out.println("2. Strings in switch Statements");
System.out.println(getTypeOfDayWithSwitchStatement("Monday"));
}
}
class TheTryWithResourcesStatement {
// The following example reads the first line from a file.
// It uses an instance of FileReader and BufferedReader to read data from the file.
// FileReader and BufferedReader are resources that must be closed after the program is finished with it:
private String readFirstLineFromFile(String path) throws IOException {
try ( FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr)) {
return br.readLine();
}
}
// In this example, the resources declared in the try-with-resources statement are a FileReader and a BufferedReader.
// The declaration statements of these resources appear within parentheses immediately after the try keyword.
// The classes FileReader and BufferedReader, in Java SE 7 and later, implement the interface java.lang.AutoCloseable.
// Because the FileReader and BufferedReader instances are declared in a try-with-resource statement, they 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 try statement completes normally or abruptly.
// The following example uses a finally block instead of a try-with-resources statement:
private String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr);
try {
return br.readLine();
}
finally {
br.close();
fr.close();
}
}
// However, this example might have a resource leak. A program has to do more than rely on the garbage collector (GC) to reclaim a resource's memory when it's finished with it. The program must also release the resoure back to the operating system, typically by calling the resource's close method.
// However, if a program fails to do this before the GC reclaims the resource, then the information needed to release the resource is lost.
// The resource, which is still considered by the operaing system to be in use, has leaked.
// In this example, if the readLine method throws an exception, and the statement br.close() in the finally block throws an exception, then the FileReader has leaked.
// Therefore, use a try-with-resources statement instead of a finally block to close your program's resources.
// 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;
/*
// Suppressed Exceptions
// An exception can be thrown from the block of code associated with the try-with-resources statement.
// In the example writeToFileZipFileContents, 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 ZipFile 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 block is the one that is thrown by the writeToFileZipFileContents method.
// You can retrieve these suppressed exceptions by calling the Throwable.getSuppressed method from the exception thrown by the try block.
*/
// The following example retrieves the names of the files packaged in the zip file zipFileName and creates a text file that contains the names of these files:
private void writeToFileZipFileContents(String zipFileName,
String outputFileName)
throws java.io.IOException {
java.nio.charset.Charset charset =
java.nio.charset.StandardCharsets.US_ASCII;
java.nio.file.Path outputFilePath =
java.nio.file.Paths.get(outputFileName);
// Open zip file and create output file with
// try-with-resources statement
try (
java.util.zip.ZipFile zf =
new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer =
java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) {
// Enumerate each entry
for (java.util.Enumeration entries =
zf.entries(); entries.hasMoreElements();) {
// Get the entry name and write it to the output file
String newLine = System.getProperty("line.separator");
String zipEntryName =
((java.util.zip.ZipEntry)entries.nextElement()).getName() +
newLine;
writer.write(zipEntryName, 0, zipEntryName.length());
System.out.println("Zip Entry Name: " + zipEntryName.trim());
}
}
}
// In this example, the try-with-resources statement contains two declarations that are separated by a semicolon: ZipFile and BufferedWriter.
// When the block of code that directly follows it terminates, either normally or because of an exception, the close methods of the BufferedWriter and ZipFile objects are automatically called in this order.
// Note that the close methods of resources are called in the opposite order of their creation.
// The following example uses a try-with-resources statement to automatically close a java.sql.Statement object:
private void viewTable(Connection con) throws SQLException {
String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES";
try (Statement stmt = con.createStatement()) {
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
String coffeeName = rs.getString("COF_NAME");
int supplierID = rs.getInt("SUP_ID");
float price = rs.getFloat("PRICE");
int sales = rs.getInt("SALES");
int total = rs.getInt("TOTAL");
System.out.println(coffeeName + ", " + supplierID + ", " + price + ", " + sales + ", " + total);
}
} catch (SQLException e) {
JDBCTutorialUtilities.printSQLException(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.
public void print() throws IOException {
System.out.println("3. The try-with-resources Statement");
System.out.println("The first line from a file");
Path currentPath = Paths.get(".");
Path filePath = currentPath.resolve("Java7.java");
Path pathFileName = filePath.getFileName();
System.out.println(readFirstLineFromFile(pathFileName.toString()));
System.out.println("Prior to Java SE 7, you can use a finally block to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly.");
System.out.println(readFirstLineFromFileWithFinallyBlock(pathFileName.toString()));
System.out.println("However, if a program fails to do this before the GC reclaims the resource, then the information needed to release the resource is lost.");
System.out.println("The resource, which is still considered by the operaing system to be in use, has leaked.");
System.out.println("In Java SE 7 and later, you can retrieve suppressed exceptions");
System.out.println("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 block is the one that is thrown by the writeToFileZipFileContents method.");
System.out.println("Retrieve the names of the files packaged in the zip file zipFileName and creates a text file that contains the names of these files.");
writeToFileZipFileContents("Archive.zip", "Java SE 7.txt");
}
}
class JDBCTutorialUtilities {
public static void printSQLException(SQLException ex) {
for (Throwable e : ex) {
if (e instanceof SQLException) {
if (ignoreSQLException(((SQLException)e).getSQLState()) == false) {
e.printStackTrace(System.err);
System.err.println("SQLState: " + ((SQLException)e).getSQLState());
System.err.println("Error Code: " + ((SQLException)e).getErrorCode());
System.err.println("Message: " + e.getMessage());
Throwable t = ex.getCause();
while (t != null) {
System.out.println("Cause: " + t);
t = t.getCause();
}
}
}
}
}
public static boolean ignoreSQLException(String sqlState) {
if (sqlState == null) {
System.out.println("The SQL state is not defined!");
return false;
}
// X0Y32: Jar file already exists in schema
if (sqlState.equalsIgnoreCase("X0Y32")) {
return true;
}
// 42Y55: Table already exists in schema
if (sqlState.equalsIgnoreCase("42Y55")) {
return true;
}
return false;
}
}
class CatchingMultipleExceptionTypesAndRethrowingExceptions {
public void handleMoreThanOneTypeOfException() throws Exception {
// Handling More Than One Type of Exception
// In Java SE 7 and later, 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.
try {
throw new Exception();
}
// Consider the following example, which contains duplicate code in each of the catch blocks:
/*
catch (IOException ex) {
System.out.println(ex);
throw ex;
} catch (SQLException ex) {
System.out.println(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 and later, eliminates the duplicated code:
catch (IOException|SQLException ex) {
System.out.println(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: 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.
// 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.
}
static class FirstException extends Exception { }
static class SecondException extends Exception { }
public void rethrowException(String exceptionName) throws Exception {
// 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:
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 determineRethrowException(String exceptionName)
throws FirstException, SecondException {
try {
if (exceptionName.equals("First")) {
throw new FirstException();
}
else {
throw new SecondException();
}
}
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 and later, 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 andSecondException.
*/
public void print() {
System.out.println("4. Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking");
try {
System.out.println("In Java SE 7 and later, a single catch block can handle more than one type of exception.");
System.out.println("This feature can reduce code duplication and lessen the temptation to catch an overly broad exception.");
handleMoreThanOneTypeOfException();
} catch (Exception ex) {
ex.printStackTrace();
}
try {
System.out.println("The Java SE 7 compiler performs more precise analysis of rethrown exceptions than earlier releases of Java SE.");
System.out.println("This enables you to specify more specific exception types in the throws clause of a method declaration.");
rethrowException("Second");
} catch (Exception ex) {
ex.printStackTrace();
}
try {
System.out.println("The Java SE 7 compiler can determine that the exception thrown by the statement throw e must have come from the try block.");
determineRethrowException("First");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
class UnderscoresInNumericLiterals {
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;
// 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
// float pi1 = 3_.1415F; // Invalid; cannot put underscores adjacent to a decimal point
// float pi2 = 3._1415F; // Invalid; cannot put underscores adjacent to a decimal point
// long socialSecurityNumber1 = 999_99_9999_L; // Invalid; cannot put underscores prior to an L suffix
// int x1 = _52; // This is an identifier, not a numeric literal
int x2 = 5_2; // OK (decimal literal)
// int x3 = 52_; // Invalid; cannot put underscores at the end of a literal
int x4 = 5_______2; // OK (decimal literal)
// int x5 = 0_x52; // Invalid; cannot put underscores in the 0x radix prefix
// int x6 = 0x_52; // Invalid; cannot put underscores at the beginning of a number
int x7 = 0x5_2; // OK (hexadecimal literal)
// int x8 = 0x52_; // Invalid; cannot put underscores at the end of a number
int x9 = 0_52; // OK (octal literal)
int x10 = 05_2; // OK (octal literal)
// int x11 = 052_; // Invalid; cannot put underscores at the end of a number
public void print() {
System.out.println("5. Underscores in Numeric Literals");
System.out.println(String.format("Credit Card Number: %d", creditCardNumber));
System.out.println(String.format("Social Security Number: %d", socialSecurityNumber));
System.out.println(String.format("pi: %f", pi));
System.out.println(String.format("hexBytes: %d", hexBytes));
System.out.println(String.format("maxLong: %d", maxLong));
System.out.println(String.format("nybbles: %d", nybbles));
System.out.println(String.format("bytes: %d", bytes));
System.out.println(String.format("OK (decimal literal): %d", x2));
System.out.println(String.format("OK (decimal literal): %d", x4));
System.out.println(String.format("OK (hexadecimal literal): %d", x7));
System.out.println(String.format("OK (octal literal) %d", x9));
System.out.println(String.format("OK (octal literal) %d", x10));
}
}
class TypeInferenceForGenericInstanceCreation {
public void print() {
System.out.println("6. Type Inference for Generic Instance Creation");
// 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>> mapHash = 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>> mapHashEmpty = 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:
// unchecked conversion warning // % javac Java7.java -Xlint:unchecked
@SuppressWarnings({ "unchecked", "varargs"})
Map<String, List<String>> mapHashUncheckedWarning = new HashMap();
// 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> lst = new ArrayList<>();
// lst.add("A");
// The following statement should fail since addAll expects
// Collection<? extends String>
// lst.addAll(new ArrayList<>());
// 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 compiles:
// The following statements compile:
List<? extends String> lstExtends = new ArrayList<>();
lst.addAll(lstExtends);
// Consider the following instantiation of the class GenericConstructors, which is valid in Java SE 7 and prior releases:
GenericConstructors<Integer> constructorsGeneric = new GenericConstructors<Integer>("<Integer> valid in Java SE 7 and prior releases");
// This statement creates an instance of the parameterized type GenericConstructors<Integer>; the statement explicitly specifies the type Integer for the formal type parameter, X, of the generic class GenericConstructors<X>.
// Note that the constructor for this generic class contains a formal type parameter, T.
// The compiler infers the type String for the formal type parameter, T, of the constructor of this generic class (because the actual parameter of this constructor is a String object).
// Compilers from releases prior to Java SE 7 are able to infer the actual type parameters of generic constructors, similar to generic methods.
// However, the compiler in Java SE 7 can infer the actual type parameters
// Consider the following example which is valid for Java SE 7 and later:
GenericConstructors<Integer> constructorsGenericJavaSE7 = new GenericConstructors<>("<> valid for Java SE 7 and later");
// In this example, the compiler infers the type Integer for the formal type parameter, X, of the generic class GenericConstructors<X>.
// It infers the type String for the formal type parameter, T, of the constructor of this generic class.
}
}
// Type Inference and Generic Constructors of Generic and Non-Generic Classes
// Note that constructors can be generic (in other words, declare their own formal type parameters) in both generic and non-generic classes.
// Consider the following example:
class GenericConstructors<X> {
<T> GenericConstructors(T t) {
System.out.println("Type Inference and Generic Constructors of Generic and Non-Generic Classes:" + t);
}
}
class ImprovedCompilerWarningsAndErrors {
@SuppressWarnings({ "unchecked", "varargs"})
public void print() {
System.out.println("7. Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods");
List l = new ArrayList<Number>();
List<String> ls = l; // unchecked warning // % javac Java7.java -Xlint:unchecked // @SuppressWarnings
l.add(0, new Integer(1)); // another unchecked warning // % javac Java7.java -Xlint:unchecked // @SuppressWarnings({ "unchecked", "varargs"})
// String s = ls.get(0); // ClassCastException is thrown // java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
List<String> stringListA = new ArrayList<String>();
List<String> stringListB = new ArrayList<String>();
ArrayBuilder.addToList(stringListA, "Alpha", "Beta", "Gamma");
ArrayBuilder.addToList(stringListA, "Delta", "Epsilon", "Zeta");
List<List<String>> listOfStringLists = new ArrayList<List<String>>();
// Heap Pollution
// warning: [unchecked] unchecked generic array creation for varargs parameter of type List<String>[]
// % javac Java7.java -Xlint:unchecked // unless @SafeVarargs at method definitions
ArrayBuilder.addToList(listOfStringLists, stringListA, stringListB);
ArrayBuilder.addToListAlpha(listOfStringLists, stringListA, stringListB); // @SuppressWarnings("varargs") does not suppress warnings from call site.
ArrayBuilder.addToListBeta(listOfStringLists, stringListA, stringListB);
// Heap Pollution
// warning: [unchecked] unchecked generic array creation for varargs parameter of type List<String>[]
// % javac Java7.java -Xlint:unchecked
ArrayBuilder.faultyMethod(Arrays.asList("Hello!"), Arrays.asList("World!"));
System.out.println("7. Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods: @SafeVarargs");
System.out.println("7. Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods: @SuppressWarnings({ \"unchecked\", \"varargs\"})");
System.out.println("Unlike the @SafeVarargs annotation, the @SuppressWarnings(\"varargs\") does not suppress warnings generated from the method's call site.");
/*
Note: In Java SE 5 and 6, it is the responsibility of the programmer who calls a varargs method that has a non-reifiable varargs formal parameter
to determine whether heap pollution would occur. However, if this programmer did not write such a method, he or she cannot easily determine
this. In Java SE 7, it is the responsibility of the programmer who writes these kinds of varargs methods to ensure that they properly handle the
varargs formal parameter and ensure heap pollution does not occur.
*/
}
}
class ArrayBuilder {
// warning: [unchecked] Possible heap pollution from parameterized vararg type T
// % javac Java7.java -Xlint:unchecked
// Suppressing Warnings from Varargs Methods with Non-Reifiable Formal Parameters
@SafeVarargs // final method
public static <T> void addToList(List<T> listArg, T...elements) {
for (T x : elements) {
listArg.add(x);
}
}
// warning: [unchecked] Possible heap pollution from parameterized vararg type List<String>
// % javac Java7.java -Xlint:unchecked
// Suppressing Warnings from Varargs Methods with Non-Reifiable Formal Parameters
@SafeVarargs // final method
public static void faultyMethod(List<String>...l) {
Object[] objectArray = l; // Valid
objectArray[0] = Arrays.asList(new Integer(42));
// String s = l[0].get(0); // ClassCastException thrown here
}
@SafeVarargs
@SuppressWarnings({ "unchecked", "varargs"}) // Unlike the @SafeVarargs annotation, the @SuppressWarnings("varargs") does not suppress warnings generated from the method's call site.
public static < T > void addToListAlpha(List < T > listArg, T... elements) {
for (T x : elements) {
listArg.add(x);
}
}
@SafeVarargs
public static < T > void addToListBeta(List < T > listArg, T... elements) {
for (T x : elements) {
listArg.add(x);
}
}
}
class Java7 {
public static void main(String[] args) throws IOException {
SystemProperties propertiesSystem = new SystemProperties();
propertiesSystem.print();
BinaryLiterals literalsBinary = new BinaryLiterals();
literalsBinary.print();
System.out.println();
StringsInSwitchStatements switchStatementsStrings = new StringsInSwitchStatements();
switchStatementsStrings.print();
System.out.println();
TheTryWithResourcesStatement tryWithResourcesStatement = new TheTryWithResourcesStatement();
tryWithResourcesStatement.print();
System.out.println();
CatchingMultipleExceptionTypesAndRethrowingExceptions multipleExceptionTypesAndRethrowing = new
CatchingMultipleExceptionTypesAndRethrowingExceptions();
multipleExceptionTypesAndRethrowing.print();
System.out.println();
UnderscoresInNumericLiterals numericLiteralsUnderscores = new UnderscoresInNumericLiterals();
numericLiteralsUnderscores.print();
System.out.println();
TypeInferenceForGenericInstanceCreation inferenceForGenericInstance = new TypeInferenceForGenericInstanceCreation();
inferenceForGenericInstance.print();
System.out.println();
ImprovedCompilerWarningsAndErrors compilerWarningsAndErrorsImproved = new ImprovedCompilerWarningsAndErrors();
compilerWarningsAndErrorsImproved.print();
}
}
class SystemProperties {
public void print() {
System.out.println(String.format("OS Name: %s", System.getProperty("os.name")));
System.out.println(String.format("OS Version: %s", System.getProperty("os.version")));
System.out.println(String.format("OS Architecture: %s", System.getProperty("os.arch")));
System.out.println(String.format("Java Version: %s", System.getProperty("java.version")));
// System.getProperties().list(System.out);
System.out.println();
}
}
// Output
/*
OS Name: Mac OS X
OS Version: 10.16
OS Architecture: x86_64
Java Version: 1.7.0_80
1. Binary Literals
An 8-bit 'byte': 33
A 16-bit 'short' value: -24251
Some 32-bit 'int' values: -1589272251, 5, 5
A 64-bit 'long' value: -6825872339779608251
Binary literals can make relationships among data more apparent than they would be in hexadecimal or octal
49, 98, 196, 137, 19, 38, 76, 152
In hexadecimal, the relationship among the numbers is not readily apparent
49, 98, 196, 137, 19, 38, 76, 152
You can use binary integral constants in code that you can verify against a specifications document, such as a simulator for a hypothetical 8-bit microprocessor
Decoded
You can use binary literals to make a bitmap more readable
2016, 2064, 4104, 8196, 16386, -31135, -31135, -32767, -32767, -28663, -30703, 18402, 8196, 4104, 2064, 2016
2. Strings in switch Statements
Start of work week
3. The try-with-resources Statement
The first line from a file
// Java 7
Prior to Java SE 7, you can use a finally block to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly.
// Java 7
However, if a program fails to do this before the GC reclaims the resource, then the information needed to release the resource is lost.
The resource, which is still considered by the operaing system to be in use, has leaked.
In Java SE 7 and later, you can retrieve suppressed exceptions
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 block is the one that is thrown by the writeToFileZipFileContents method.
Retrieve the names of the files packaged in the zip file zipFileName and creates a text file that contains the names of these files.
Zip Entry Name: Java7.java
Zip Entry Name: Program.java
Zip Entry Name: Reference/
4. Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking
In Java SE 7 and later, 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.
java.lang.Exception
at CatchingMultipleExceptionTypesAndRethrowingExceptions.handleMoreThanOneTypeOfException(Java7.java:450)
at CatchingMultipleExceptionTypesAndRethrowingExceptions.print(Java7.java:538)
at Java7.main(Java7.java:766)
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.
CatchingMultipleExceptionTypesAndRethrowingExceptions$SecondException
at CatchingMultipleExceptionTypesAndRethrowingExceptions.rethrowException(Java7.java:490)
at CatchingMultipleExceptionTypesAndRethrowingExceptions.print(Java7.java:546)
at Java7.main(Java7.java:766)
The Java SE 7 compiler can determine that the exception thrown by the statement throw e must have come from the try block.
CatchingMultipleExceptionTypesAndRethrowingExceptions$FirstException
at CatchingMultipleExceptionTypesAndRethrowingExceptions.determineRethrowException(Java7.java:508)
at CatchingMultipleExceptionTypesAndRethrowingExceptions.print(Java7.java:553)
at Java7.main(Java7.java:766)
5. Underscores in Numeric Literals
Credit Card Number: 1234567890123456
Social Security Number: 999999999
pi: 3.141500
hexBytes: -1253794
maxLong: 9223372036854775807
nybbles: 37
bytes: -764832622
OK (decimal literal): 52
OK (decimal literal): 52
OK (hexadecimal literal): 82
OK (octal literal) 42
OK (octal literal) 42
6. Type Inference for Generic Instance Creation
Type Inference and Generic Constructors of Generic and Non-Generic Classes:<Integer> valid in Java SE 7 and prior releases
Type Inference and Generic Constructors of Generic and Non-Generic Classes:<> valid for Java SE 7 and later
7. Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods
7. Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods: @SafeVarargs
7. Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods: @SuppressWarnings({ "unchecked", "varargs"})
Unlike the @SafeVarargs annotation, the @SuppressWarnings("varargs") does not suppress warnings generated from the method's call site.
*/
// Credits:
/*
https://openjdk.org/
https://oracle.com/java/
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment