原文出处:xixicat

这是Java语言特性系列的第一篇,从java5的新特性开始讲起。初衷就是可以方便的查看语言的演进历史。

特性列表

  • 泛型

  • 枚举

  • 装箱拆箱

  • 变长参数

  • 注解

  • foreach循环

  • 静态导入

  • 格式化

  • 线程框架/数据结构

  • Arrays工具类/StringBuilder/instrument

1、泛型

所谓类型擦除指的就是Java源码中的范型信息只允许停留在编译前期,而编译后的字节码文件中将不再保留任何的范型信息。也就是说,范型信息在编译时将会被全部删除,其中范型类型的类型参数则会被替换为Object类型,并在实际使用时强制转换为指定的目标数据类型。而C++中的模板则会在编译时将模板类型中的类型参数根据所传递的指定数据类型生成相对应的目标代码。

Map<Integer, Integer> squares = new HashMap<Integer, Integer>();
  • 通配符类型:避免unchecked警告,问号表示任何类型都可以接受

public void printList(List<?> list, PrintStream out) throws IOException {
for (Iterator<?> i = list.iterator(); i.hasNext(); ) {
out.println(i.next().toString());
}
}
  • 限制类型

public static <A extends Number> double sum(Box<A> box1,Box<A> box2){
double total = 0;
for (Iterator<A> i = box1.contents.iterator(); i.hasNext(); ) {
total = total + i.next().doubleValue();
}
for (Iterator<A> i = box2.contents.iterator(); i.hasNext(); ) {
total = total + i.next().doubleValue();
}
return total;
}

2、枚举

  • EnumMap

public void testEnumMap(PrintStream out) throws IOException {
// Create a map with the key and a String message
EnumMap<AntStatus, String> antMessages =
new EnumMap<AntStatus, String>(AntStatus.class);
// Initialize the map
antMessages.put(AntStatus.INITIALIZING, "Initializing Ant...");
antMessages.put(AntStatus.COMPILING, "Compiling Java classes...");
antMessages.put(AntStatus.COPYING, "Copying files...");
antMessages.put(AntStatus.JARRING, "JARring up files...");
antMessages.put(AntStatus.ZIPPING, "ZIPping up files...");
antMessages.put(AntStatus.DONE, "Build complete.");
antMessages.put(AntStatus.ERROR, "Error occurred.");
// Iterate and print messages
for (AntStatus status : AntStatus.values() ) {
out.println("For status " + status + ", message is: " +
antMessages.get(status));
}
}
  • switch枚举

public String getDescription() {
switch(this) {
case ROSEWOOD: return "Rosewood back and sides";
case MAHOGANY: return "Mahogany back and sides";
case ZIRICOTE: return "Ziricote back and sides";
case SPRUCE: return "Sitka Spruce top";
case CEDAR: return "Wester Red Cedar top";
case AB_ROSETTE: return "Abalone rosette";
case AB_TOP_BORDER: return "Abalone top border";
case IL_DIAMONDS:
return "Diamonds and squares fretboard inlay";
case IL_DOTS:
return "Small dots fretboard inlay";
default: return "Unknown feature";
}
}

3、Autoboxing与Unboxing

将primitive类型转换成对应的wrapper类型:Boolean、Byte、Short、Character、Integer、Long、Float、Double

public static void m1(Integer i){
System.out.println("this is integer");
}
public static void m1(double d){
System.out.println("this is double");
}

m1(1)输出的是double,方法匹配时线下兼容,不考虑boxing与unboxing。

4、vararg

private String print(Object... values) {
StringBuilder sb = new StringBuilder();
for (Object o : values) {
sb.append(o.toString())
.append(" ");
}
return sb.toString();
}

5、annotation

  • Inherited表示该注解是否对类的子类继承的方法等起作用

@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface InProgress { }
  • 指定Target

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,
ElementType.METHOD,
ElementType.CONSTRUCTOR,
ElementType.ANNOTATION_TYPE})
public @interface TODO {
String value();
}
  • Target类型

public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE
}
  • rentation表示annotation是否保留在编译过的class文件中还是在运行时可读。

public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
  • 通过反射获取元信息

public class ReflectionTester {
public ReflectionTester() {
}
public void testAnnotationPresent(PrintStream out) throws IOException {
Class c = Super.class;
boolean inProgress = c.isAnnotationPresent(InProgress.class);
if (inProgress) {
out.println("Super is In Progress");
} else {
out.println("Super is not In Progress");
}
}
public void testInheritedAnnotation(PrintStream out) throws IOException {
Class c = Sub.class;
boolean inProgress = c.isAnnotationPresent(InProgress.class);
if (inProgress) {
out.println("Sub is In Progress");
} else {
out.println("Sub is not In Progress");
}
}
public void testGetAnnotation(PrintStream out)
throws IOException, NoSuchMethodException {
Class c = AnnotationTester.class;
AnnotatedElement element = c.getMethod("calculateInterest",
float.class, float.class);
GroupTODO groupTodo = element.getAnnotation(GroupTODO.class);
String assignedTo = groupTodo.assignedTo();
out.println("TODO Item on Annotation Tester is assigned to: '" +
assignedTo + "'");
}
public void printAnnotations(AnnotatedElement e, PrintStream out)
throws IOException {
out.printf("Printing annotations for '%s'%n%n", e.toString());
Annotation[] annotations = e.getAnnotations();
for (Annotation a : annotations) {
out.printf(" * Annotation '%s' found%n",
a.annotationType().getName());
}
}
public static void main(String[] args) {
try {
ReflectionTester tester = new ReflectionTester();
tester.testAnnotationPresent(System.out);
tester.testInheritedAnnotation(System.out);
tester.testGetAnnotation(System.out);
Class c = AnnotationTester.class;
AnnotatedElement element = c.getMethod("calculateInterest",
float.class, float.class);
tester.printAnnotations(element, System.out);
} catch (Exception e) {
e.printStackTrace();
}
}
}

6、for/in

for/in循环办不到的事情:
(1)遍历同时获取index
(2)集合逗号拼接时去掉最后一个
(3)遍历的同时删除元素

7、静态import

import static java.lang.System.err;
import static java.lang.System.out;
import java.io.IOException;
import java.io.PrintStream;
public class StaticImporter {
public static void writeError(PrintStream err, String msg)
throws IOException { // Note that err in the parameter list overshadows the imported err
err.println(msg);
}
public static void main(String[] args) {
if (args.length < 2) {
err.println(
"Incorrect usage: java com.oreilly.tiger.ch08 [arg1] [arg2]");
return;
}
out.println("Good morning, " + args[0]);
out.println("Have a " + args[1] + " day!");
try {
writeError(System.out, "Error occurred.");
} catch (IOException e) {
e.printStackTrace();
}
}
}

8、格式化

/**
* java.text.DateFormat
* java.text.SimpleDateFormat
* java.text.MessageFormat
* java.text.NumberFormat
* java.text.ChoiceFormat
* java.text.DecimalFormat
*/
public class FormatTester {
public static void printf() {
//printf
String filename = "this is a file";
try {
File file = new File(filename);
FileReader fileReader = new FileReader(file);
BufferedReader reader = new BufferedReader(fileReader);
String line;
int i = 1;
while ((line = reader.readLine()) != null) {
System.out.printf("Line %d: %s%n", i++, line);
}
} catch (Exception e) {
System.err.printf("Unable to open file named '%s': %s",
filename, e.getMessage());
}
}
public static void stringFormat() {
// Format a string containing a date.
Calendar c = new GregorianCalendar(1995, MAY, 23);
String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
// -> s == "Duke's Birthday: May 23, 1995"
System.out.println(s);
}
public static void formatter() {
StringBuilder sb = new StringBuilder();
// Send all output to the Appendable object sb
Formatter formatter = new Formatter(sb, Locale.US);
// Explicit argument indices may be used to re-order output.
formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d");
// -> " d c b a"
// Optional locale as the first argument can be used to get
// locale-specific formatting of numbers. The precision and width can be
// given to round and align the value.
formatter.format(Locale.FRANCE, "e = %+10.4f", Math.E);
// -> "e = +2,7183"
// The '(' numeric flag may be used to format negative numbers with
// parentheses rather than a minus sign. Group separators are
// automatically inserted.
formatter.format("Amount gained or lost since last statement: $ %(,.2f",
6217.58);
// -> "Amount gained or lost since last statement: $ (6,217.58)"
}
public static void messageFormat() {
String msg = "欢迎光临,当前({0})等待的业务受理的顾客有{1}位,请排号办理业务!";
MessageFormat mf = new MessageFormat(msg);
String fmsg = mf.format(new Object[]{new Date(), 35});
System.out.println(fmsg);
}
public static void dateFormat(){
String str = "2010-1-10 17:39:21";
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
try {
System.out.println(format.format(format.parse(str)));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
formatter();
stringFormat();
messageFormat();
dateFormat();
printf();
}
}

9、threading

  • uncaught exception

public class BubbleSortThread extends Thread {
private int[] numbers;
public BubbleSortThread(int[] numbers) {
setName("Simple Thread");
setUncaughtExceptionHandler(
new SimpleThreadExceptionHandler());
this.numbers = numbers;
}
public void run() {
int index = numbers.length;
boolean finished = false;
while (!finished) {
index--;
finished = true;
for (int i=0; i<index; i++) {
// Create error condition
if (numbers[i+1] < 0) {
throw new IllegalArgumentException(
"Cannot pass negative numbers into this thread!");
}
if (numbers[i] > numbers[i+1]) {
// swap
int temp = numbers[i];
numbers[i] = numbers[i+1];
numbers[i+1] = temp;
finished = false;
}
}
}
}
}
class SimpleThreadExceptionHandler implements
Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
System.err.printf("%s: %s at line %d of %s%n",
t.getName(),
e.toString(),
e.getStackTrace()[0].getLineNumber(),
e.getStackTrace()[0].getFileName());
}
}
  • blocking queue

public class Producer extends Thread {
private BlockingQueue q;
private PrintStream out;
public Producer(BlockingQueue q, PrintStream out) {
setName("Producer");
this.q = q;
this.out = out;
}
public void run() {
try {
while (true) {
q.put(produce());
}
} catch (InterruptedException e) {
out.printf("%s interrupted: %s", getName(), e.getMessage());
}
}
private String produce() {
while (true) {
double r = Math.random();
// Only goes forward 1/10 of the time
if ((r*100) < 10) {
String s = String.format("Inserted at %tc", new Date());
return s;
}
}
}
}
  • 线程池

    著名的JUC类库。

    • 每次提交任务时,如果线程数还没达到coreSize就创建新线程并绑定该任务。 所以第coreSize次提交任务后线程总数必达到coreSize,不会重用之前的空闲线程。

    • 线程数达到coreSize后,新增的任务就放到工作队列里,而线程池里的线程则努力的使用take()从工作队列里拉活来干。

    • 如果队列是个有界队列,又如果线程池里的线程不能及时将任务取走,工作队列可能会满掉,插入任务就会失败,此时线程池就会紧急的再创建新的临时线程来补救。

    • 临时线程使用poll(keepAliveTime,timeUnit)来从工作队列拉活,如果时候到了仍然两手空空没拉到活,表明它太闲了,就会被解雇掉。

    • 如果core线程数+临时线程数 >maxSize,则不能再创建新的临时线程了,转头执行RejectExecutionHanlder。默认的AbortPolicy抛RejectedExecutionException异常,其他选择包括静默放弃当前任务(Discard),放弃工作队列里最老的任务(DisacardOldest),或由主线程来直接执行(CallerRuns),或你自己发挥想象力写的一个。

10、其他

  • Arrays

Arrays.sort(myArray);
Arrays.toString(myArray)
Arrays.binarySearch(myArray, 98)
Arrays.deepToString(ticTacToe)
Arrays.deepEquals(ticTacToe, ticTacToe3)
  • Queue

    避开集合的add/remove操作,使用offer、poll操作(不抛异常)

Queue q = new LinkedList(); 采用它来实现queue
  • Override返回类型

    支持协变返回

  • 单线程StringBuilder

    线程不安全,在单线程下替换string buffer提高性能

  • java.lang.instrument

参考

Java5的新特性的更多相关文章

  1. Java5~11新特性

    Java5~11版本新特性 Java5 Java6 Java7 Java8 Java9 Java10 Java11 Java5 Java5开发代号为Tiger(老虎),于2004-09-30发行 特性 ...

  2. java 多线程 day08 java5多线程新特性

    /** * Created by chengtao on 17/12/3. */public class Thread0801_java5_Atomaic { /* 三个包: http://tool. ...

  3. 转: 【Java并发编程】之二十一:并发新特性—阻塞队列和阻塞栈(含代码)

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17511147 阻塞队列 阻塞队列是Java5并发新特性中的内容,阻塞队列的接口是Java. ...

  4. 【Java并发编程】:并发新特性—塞队列和阻塞栈

    阻塞队列 阻塞队列是Java5并发新特性中的内容,阻塞队列的接口是Java.util.concurrent.BlockingQueue,它有多个实现类:ArrayBlockingQueue.Delay ...

  5. java5、java6、java7、java8的新特性

    Java5: 1.泛型 Generics:        引用泛型之后,允许指定集合里元素的类型,免去了强制类型转换,并且能在编译时刻进行类型检查的好处. Parameterized Type作为参数 ...

  6. Java5,Java 6,Java 7,Java 8新特性

    Java5: 1.泛型 Generics:        引用泛型之后,允许指定集合里元素的类型,免去了强制类型转换,并且能在编译时刻进行类型检查的好处. Parameterized Type作为参数 ...

  7. Objective-C的新特性

    Objective-C的新特性 苹果在今年的 WWDC2012 大会上介绍了大量 Objective-C 的新特性,能够帮助 iOS 程序员更加高效地编写代码.在不久前更新的 Xcode4.4 版本中 ...

  8. Java最近版本新特性使用介绍

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 在阅读<Thinking in Java>的过程中,并发这一章出现不少新特性,工作中也有 ...

  9. Hi java新特性

    java新特性 1995.5.23 java语言 1996 jdk1.0 250个类在API 主要用在桌面型应用程序1997 jdk1.1 500 图形用户界面编程1998 jdk1.2 2300 J ...

随机推荐

  1. 第三周vim入门学习2

    一.vim重复命令 1.重复执行上次命令 在普通模式下.(小数点)表示重复上一次的命令操作 拷贝测试文件到本地目录 $ cp /etc/protocols . 打开文件进行编辑 $ vim proto ...

  2. java学习de路线建议

    我想谈一谈我的一些关于网页学习的小感悟吧.之所以是写这个的原因完全是想告诉现在还处在网页学习的初始阶段的同学一些我学习走过的弯路,但我说的也仅是我个人的理解,毕竟我只能是JavaWeb开发的新手,所以 ...

  3. Servlet学习小结

    最近有点小累啊,上课平均一天6小时,再去修一修代码就没什么多的时间了.现在写我最近学习的成果:想想最近软件工程老师留的题目,我还有一些重要的地方没有想清楚.题目是这样的:生成四则运算的题目,算术题目包 ...

  4. Servlet 3.0对上传的支持

    Servlet 2.5 进行上传   首先对表单的要求     ->method ="post"    ->enctype="multipart/form-d ...

  5. 【CSAPP笔记】8. 汇编语言——数据存储

    下面介绍一些C语言中常见的特殊的数据存储方式,以及它们在汇编语言中是如何表示的. 数组 数组是一种将标量数据聚集成更大数据类型的方式.实现数组的方式其实十分简单,也非常容易翻译成机器代码.C语言的一个 ...

  6. grunt入门讲解6:grunt使用步骤和总结

    Grunt是啥? 很火的前端自动化小工具,基于任务的命令行构建工具. Grunt能帮我们干啥? 假设有这样一个场景: 编码完成后,你需要做以下工作 HTML去掉注析.换行符 - HtmlMin CSS ...

  7. Beta阶段DAY3

    一.提供当天站立式会议照片一张 二.每个人的工作 1.讨论项目每个成员的昨天进展 刘阳航:尝试改进UI,美化界面. 林庭亦:调整难度设置. 郑子熙:尝试改进UI,美化界面. 陈文俊:调整难度设置. 2 ...

  8. laravel中的Contracts, ServiceContainer, ServiceProvider, Facades关系

    Contracts, ServiceContainer, ServiceProvider, Facades  Contracts 合同,契约,也就是接口,定义一些规则,每个实现此接口的都要实现里面的方 ...

  9. (转)web开发流程

    a.项目经理与公司决策层的沟通,以确定这个需求有没有足够的人手和可行性去实现,以及与现有产品的依存关系. b.公司决策层与市场/策划部门的交流,这个过程将进行的相当充分,并且是反复.长期的,它致力于从 ...

  10. widows终端远程连接Linux服务器

    一.前言 为什么不是远程连接Linux服务器? 因为我不会,远程连接window我就用电脑自带的“远程桌面连接”. 以下所述都是在CentOS操作系统下的. 服务器刚换成Linux的时候很迷茫,感觉无 ...