关于JDK7新特性……

别的还没有觉得好到哪里,jdk7 里有了enum 和 switch String了?

Improved Type Inference

i. 具体化泛型(Reified generics)

The addition of generics to the language greatly improved compile time type checking and largely eliminated the need for casting. Unfortunately it also increased the verbosity of declarations, for example:

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

As a result, generic declarations often require multiple lines. It would be nice if you could omit the second occurrence of the type parameters (<String, List<String>>) and let the compiler figure it out ("constructor type inference"). This would remove the redundancy from the declaration, geatly enhancing readability and ease-of-use:

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

ii. Argument Positions

The result of a generic method, such as:

public <E> Set<E> emptySet() { ... }

may be used on the right-hand side of an assignment:

Set<Person> honestPoliticians = Collections.emptySet();

The compiler's type-inference mechanism figures out that the type parameter to the emptySet invocation is Person. It seems reasonable that the compiler should be able to infer the type when the result of such a generic method invocation is passed to another method:

void timeWaitsFor(Set<Man> people) { ... }

...

timeWaitsFor(Collections.emptySet()); // * Won't compile!

Sadly, this is not allowed. The specification currently requires an explicit type argument under these circumstances:

timeWaitsFor(Collections.<Man>emptySet());

Not only are explicit type arguments awkward, but many programmers are unfamiliar with them and unable to cope when the compiler requires them. With inference in argument positions, the explicit type argument is rarely required and the starred method invocation above becomes legal.

Enum(枚举) java 终于在枚举这里下功夫了!

Enum constants can safely be compared for equality use the == operator. All enum types implement Comparable, so it stands to reason that it should be possible to compare constants of an enumerated type for order using the <, >, <=, and >= operators. Unfortunately, it isn't, so programmers are forced to litter their code with calls to the compareTo method:

enum Size { SMALL, MEDIUM, LARGE }

if (mySize.compareTo(yourSize) >= 0)

System.out.println("You can wear my shirt.");

If the <, >, <=, and >= operators worked for enums, this code could be replaced by the clearer:

if (mySize >= yourSize)

System.out.println("You can wear my shirt.");

String Switch (支持 switch中String类型)

Information often comes into programs in string form, and some action (often translation into another form) takes place depending on the string value. For example, the following method translates strings to boolean values:

static boolean booleanFromString(String s) {
if (s.equals("true")) {
return true;
} else if (s.equals("false")) {
return false;
} else {
throw new IllegalArgumentException(s);
}
}

This code is not pretty, and somewhat bug-prone. If it were possible to switch on string values, this code could be replaced by the prettier and safer:

static boolean booleanFromString(String s) {
switch(s) {
case "true":
return true;
case "false":
return false;
}
throw new IllegalArgumentException(s);
}

链状调用:(Chained Invocations

Some mutation-based APIs have a number of methods that return void. This is common in the factory pattern:

class Factory {

void setSomething(Something something) { ... }

void setOther(Other other) { ... }

Thing result() { ... }


}

Using such a class can be awkward


Factory fac = new Factory();

fac.setSomething(something);

fac.setOther(other);
Thing thing = fac.result();

With chained invocations, you can reuse the receiver of the previous invocation and chain the calls together:

Thing thing = new Factory()

.setSomething(something)

.setOther(other)

.result();
With this language support, it is much easier to define "fluent" APIs.

扩展方法 :(Extension methods)

Existing interfaces cannot be extended with additional methods without breaking some clients. Instead, functionality is typically "added to an interface" by static methods in a separate utility class. Using them is somewhat awkward:

List<String> list = ...;

Collections.sort(list);

With extension methods, client can designate utility methods to act as if they were members of the interface (or class)

import static java.util.Collections.sort;

list.sort();



Improved Catch Clauses

i. 多重捕捉异常

It is often necessary to do the same thing when one of several exceptions occurs. Currently the only way to do this is to duplicate code in multiple catch clauses:

try {
return klass.newInstance();
} catch (InstantiationException e) {
throw new AssertionError(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}

It may be tempting to replace several catch clauses with one for the class that is the "least common ancestor" of the each of the exception types in question:

// Broken - catches exceptions that should be allowed to propagate!

try {
return klass.newInstance();
} catch (Exception e) {
throw new AssertionError(e);
}

Unfortunatley this does not have the correct semantics. In the case of this example, it erroneously wraps unchecked exceptions in assertion errors. To solve this problem, we propose that it be possible to catch two or more exception types in a single catch clause:

try {
return klass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new AssertionError(e);
}

ii. Improved Checking for Rethrown Exceptions

It is not uncommon that you want to catch an exception, perform some action, and rethrow the exception:

try {

doable.doIt(); // Specified to throw several different exceptions


} catch (Throwable ex) {

logger.log(ex);

throw ex; // Won't compile unless method is specified to throw Throwable!

}

Unfortunately, it is not generally possible to do this, as the resulting catch clause throws the type of exception that was caught, which the enclosing method is typically not specified to throw. To get around this, programmers often wrap the exception prior to rethrowing it:

try {
doable.doIt();

} catch (Throwable ex) {

logger.log(ex);

throw new WrappedException(ex); // Obscures exception type!

}

If a caught exception is declared final, it is safe to rethrow any caught exception:

try {

doable.doIt();

} catch (final Throwable ex) {

logger.log(ex);

throw ex;

}

Because the catch parameter is final, it can only hold exceptions that are thrown from the try block. Exception checking should take advantage of that fact: the compiler should treat this rethrown exception as if it can throw only checked exceptions that occur in the try block.

你可能感兴趣的:(JDK7)