20年Java发展历程(1995-2015)

Java语言作为现在最流行的编程语言之一,它已经经历了整整20年的发展。虽然它[url=http://rensanning.iteye.com/blog/1843545]有很多不足[/url],虽然现在有很多的开发语言,但对于规模大、生命周期长的项目来说Java仍然是一个很好的选择。

[b](0)Java由来[/b]
[list][*]1991年1月 Green Project启动,致力于家用电器智能化。
[*]1991年2月 James Gosling作为Green Project的软件负责人开始选择C++作为开发语言,最后发现C++不能满足需要,所以决定开发一门新语言,取名Oak。
[*]1991年4月 Ed Frank加入Green Project领导硬件开发,组建Star-seven (*7) Project目的是开发一个硬件原型,展示Green Project的功能。
[*]1991年6月 James Gosling开始编写Oak解释器。
[*]1992年3月 由于Oak已经被另一门语言使用,改名为Java。
[*]1992年9月 James Gosling亲自用PDA样机演示Star-seven (*7) [url=https://www.youtube.com/watch?v=1CsTH9S79qI]https://www.youtube.com/watch?v=1CsTH9S79qI[/url]
[*]1992年11月 Green project从Sun公司独立出来成立FirstPerson。
[*]1993年2月 由于Green Project不是很成功,FirstPerson失去了时代华纳的机顶盒交互系统订单。开发重心从家庭消费电子产品转到了电视盒机顶盒的相关平台上。
[*]1993年9月 Arthur Van Hoff加入,致力于交互平台上的应用开发。
[*]1994年6月 FirstPerson解散,所有人回归Sun。启动Liveoak,使用Oak开发一个新的操作系统。
[*]1994年7月 Patrick Naughton做了一个浏览器Era可以使Java在里边运行,Liveoak计划进行了调整,使得Oak语言支持互联网。
[*]1994年9月 Naughton和Jonatha Payne做了一个基于Java的浏览器HotJava(开始叫WebRunner),获得了管理层的广泛认可。
[*]1994年10月 Arthur Van Hoff使用Java编写了Java compiler,之前James Gosling使用C写的。[/list]
[img]http://dl2.iteye.com/upload/attachment/0106/9796/44955313-5e14-3c22-bf6e-866b9654f5df.jpg[/img]

[b](1)JDK Alpha and Beta (1995)[/b]
[list][*]1995年5月23日 在SunWorld Conference上Sun正式发布Java 1.0α和HotJava,这一年Windows95和IE 1.0发布(微软的巅峰时代)
[*]1995年6月 Netscape浏览器支持Java
[*]1995年10月 Java 1.0β发布
[*]1995年12月 Microsoft在IE中支持Java[/list]
[b](2)Java 1.0(JDK1.0) (1996/01/23) Oak[/b]
Sun的slogan“Write once, run anywhere”,但最开始Java存在大量问题,变成了“Write once,debug everything”。同时期(95-96)的语言还有:JS、Ruby、PHP、Delphi、ColdFusion、OCaml、Ada95。

[b](3)Java 1.1(JDK1.1) (1997/02/19) Sparkler[/b]
Sparkler (v1.1.4), Pumpkin (v1.1.5), Abigail (v1.1.6), Brutus (v1.1.7) and Chelsea (v1.1.8)。
Microsoft推出J++(实现了函数指针,C#前身),扯不尽的官司。

内部类Inner Class
public class InnerClassSample extends java.applet.Applet {
public class ApproceListner implements ActionListener { // 内部类
public void actionPerformed(final ActionEvent e) {
}
}
public void init() {
Button approveButton = new Button("OK");
approveButton.addActionListener(new ApproceListner());
this.add(approveButton);
}
}

匿名类Anonymous Class
public class AnonymousClassSample extends java.applet.Applet {
public void init() {
Button approveButton = new Button("OK");
approveButton.addActionListener(new ActionListener() { // 匿名类
public void actionPerformed(final ActionEvent e) {
}
});
this.add(approveButton);
}
}

类字面常量Class literal (广发用于反射和泛型)
// 用于反射和泛型
final Class a = List.class;
final Class b = String.class;
final Class c = double.class;
final Class d = int[][].class;

反射Reflection(Introspection only)
 BeanInfo bi = Introspector.getBeanInfo(Class.forName("com.rensanning.java.feature.jdk1_1.Rectangle"));

PropertyDescriptor props[] = bi.getPropertyDescriptors();
for (int i = 0; i < props.length; i++) {
PropertyDescriptor pd = props[i];
System.out.println( pd.getName()+" "+pd.getPropertyType()+" "+
pd.getReadMethod()+"/"+pd.getWriteMethod() );
}
System.out.println("------------");

MethodDescriptor methods[] = bi.getMethodDescriptors();
for (int i = 0; i < methods.length; i++) {
MethodDescriptor md = methods[i];
System.out.println(md.getMethod().toString());
}

数据库连接JDBC (Java Database Connectivity)
[quote]JDK 1.1 = JDBC 1.0
JDK 1.2 = JDBC 2.0
JDK 1.4 = JDBC 3.0
JDK6 = JDBC 4.0
JDK7 = JDBC 4.1[/quote]
// Loading and Registering Drivers
Class.forName("oracle.jdbc.driver.OracleDriver");

// Connecting to a Database
Connection con = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:ug", "username", "password");

// Creating and Executing Statements
Statement stmt = con.createStatement();

// Executing Inserts, Updates, and Deletes
int rowCount = stmt.executeUpdate("INSERT INTO branch VALUES (20, 'Richmond Main', " +
"'18122 No.5 Road', 'Richmond', 5252738)");

// Executing Queries
ResultSet rs = stmt.executeQuery("SELECT * FROM branch");
while(rs.next()) {
branchID = rs.getInt(1);
branchName = rs.getString("branch_name");
branchAddr = rs.getString(3);
branchCity = rs.getString("branch_city");
branchPhone = rs.getInt(5);
. . .
}

// Close resources
rs.close();
stmt.close();
con.close();

JavaBeans、RMI (Remote Method Invocation) (也叫RPC) EJB的基础
public class RmiSample {
public static void main(String[] args) throws Exception {
System.setProperty("java.rmi.server.hostname", "127.0.0.1");
new RmiServer();
new RmiClient();
}
}

interface Rmi extends Remote {
public String getMessage() throws RemoteException;
}

class RmiImpl implements Rmi, Serializable {
@Override
public String getMessage() throws RemoteException {
return "RmiImpl#message";
}
}

class RmiServer {
public RmiServer() throws RemoteException {
Remote r = createObject();
regist(r);
}
Remote createObject() throws RemoteException {
Rmi rs = new RmiImpl();
Remote r = UnicastRemoteObject.exportObject(rs, 0);
return r;
}
void regist(Remote r) throws RemoteException {
// 默认端口是1099:Registry.REGISTRY_PORT
Registry registry = LocateRegistry.createRegistry(9527);
registry.rebind("RmiName", r);
}
}

class RmiClient {
public RmiClient() throws Exception {
Rmi rs = lookup();
System.out.println(rs.getMessage());
}
Rmi lookup() throws MalformedURLException, RemoteException, NotBoundException {
Remote r = Naming.lookup("//127.0.0.1:9527/RmiName");
return (Rmi) r;
}
}


[b](4)J2SE 1.2(J2SDK1.2) (1998/12/08) Playground[/b]
集合框架Collections Framework
// 旧写法(JDK1.1)
Vector v = new Vector();
v.addElement("1");
v.addElement("2");
v.addElement("3");
Enumeration e = v.elements();
while (e.hasMoreElements())
System.out.println(e.nextElement());
v.removeElement("1");
int n = v.size();
for (int i = 0; i < n; i++)
System.out.println(v.elementAt(i));

// 新写法(JDK1.2)
List l = new ArrayList();
l.add("1");
l.add("2");
l.add("3");
Iterator it = l.iterator();
while (it.hasNext())
System.out.println(it.next());
l.remove("1");
int s = l.size();
for (int i = 0; i < s; i++)
System.out.println(l.get(i));

基础图形库Java Foundation Classes (JFC) 包含Swing、AWT、Java2D**********[url=http://www.amazon.com/dp/0596004087/]《Java Swing》[/url]

[b](5)J2SE 1.3(J2SDK1.3) (2000/05/08) Kestrel[/b]
动态代理Dynamic Proxy(用于Spring等AOP/DI框架、EasyMock等mock框架)
public class DynamicProxySample {

public static void main(String[] args) {
MyInterface myInterfaceReal = new MyClass();
InvocationHandler handler = new MyInvocationHandler(myInterfaceReal);

MyInterface myInterface = (MyInterface) Proxy.newProxyInstance(
MyClass.class.getClassLoader(),
MyClass.class.getInterfaces(),
handler);
String ret = myInterface.sayHello("JAVA");

System.out.println(ret);
}

}

class MyInvocationHandler implements InvocationHandler {
private Object target;

public MyInvocationHandler(Object target) {
this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("invoke method:" + method.getName());
Object ret = method.invoke(this.target, args);
System.out.println("invoke result:" + ret.toString());
return ret;
}
}

interface MyInterface {
String sayHello(String name);
}

class MyClass implements MyInterface {
public String sayHello(String name) {
System.out.println("hello! " + name);
return "hello!";
}
}

声音接口Java Sound
// Simple Audio Player
URL soundFile = new URL("http://www.wav-sounds.com/cartoon/bugsbunny1.wav");
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundFile);

AudioFormat audioFormat = audioInputStream.getFormat();
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
line.open(audioFormat);
line.start();

int nBytesRead = 0;
byte[] abData = new byte[128000];
while (nBytesRead != -1) {
try {
nBytesRead = audioInputStream.read(abData, 0, abData.length);
} catch (IOException e) {
e.printStackTrace();
}
if (nBytesRead >= 0) {
line.write(abData, 0, nBytesRead);
}
}

line.drain();
line.close();


[b](6)J2SE 1.4(J2SDK1.4) (2002/2/6-2008/10) Merlin [url=https://jcp.org/en/jsr/detail?id=59]JSR 59[/url][/b]
1998年成立的JCP发布的第一版本

断言Assertions
int i = 1;
// OK
assert i == 1;
System.out.println("1");
// AssertionError
assert i == 2 : "i = "+ i;
System.out.println("2");

正则表达式Regular Expressions
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);

if (matcher.matches()) {
System.out.println("[" + input + "] matches [" + pattern.pattern() + "]");
} else {
System.out.println("[" + input + "] DON'T matches [" + pattern.pattern() + "]");
}

新的输入与输出操作New I/O***********[url=http://www.amazon.com/dp/0596002882/]《Java NIO》[/url]
String text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

try {
FileOutputStream stream = new FileOutputStream("c://test.txt");
FileChannel channel = stream.getChannel();

byte[] bytes = text.getBytes();
ByteBuffer buffer = ByteBuffer.wrap(bytes);

channel.write(buffer);

channel.close();
stream.close();
} catch (Exception ex) {
ex.printStackTrace();
}

链式异常Chained Exception
public static void test() throws TestException {
try {
throw new InterruptedException();
} catch (InterruptedException ex) {
throw new TestException(ex);
}
}

日志接口Logging API
Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
logger.info("info");
logger.warning("warning");
logger.severe("severe");

图像接口Image I/O API
String sourceFile = "c://test.jpg";
String destinationFile = "c://test-new.png";
File source = new File(sourceFile);
File dest = new File(destinationFile);
String extension = getSuffix(destinationFile);

try {
BufferedImage image = ImageIO.read(source);
ImageIO.write(image, extension, dest);
} catch (IOException ex) {
ex.printStackTrace();
}

打印Print Service
URL url = new URL("https://www.baidu.com/img/bdlogo.png");
DocFlavor docFlavor = DocFlavor.URL.PNG;
Doc doc = new SimpleDoc(url, docFlavor, null);

PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet();
attrs.add(new Copies(1));
attrs.add(MediaSizeName.ISO_A4);

PrintService[] printServices = PrintServiceLookup.lookupPrintServices(docFlavor, attrs);

PrintService printService = ServiceUI.printDialog(null, 100, 100, printServices, printServices[0], docFlavor, attrs);

if (printService == null) {
return;
}

printService.createPrintJob().print(doc, attrs);


[b](7)J2SE 5.0(JDK5.0) (2004/9/30-2009/10) Tiger [url=https://jcp.org/en/jsr/detail?id=176]JSR 176[/url][/b]
泛型Generics**********[url=http://www.amazon.com/dp/0596527756/]《Java Generics》[/url]
public class GenericSample {

public static void main(String[] args) {
// 实例生成时指定类型
MyClass<String, String> mc = new MyClass<String, String>();
mc.setKeyValue("1", "test");
String key = mc.getKey();
System.out.println("key = " + key);
}

}
class MyClass<K, V> {
private K key;
private V value;
public void setKeyValue(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}

枚举Enums
// 旧写法
public static final int APPLE = 0;
public static final int ORANGE = 1;
public static final int GRAPE = 2;

// 新写法
enum Fruit {
APPLE, ORANGE, GRAPE
}

public static void main(String[] args) {
Fruit fruit = Fruit.ORANGE;
if (fruit == Fruit.GRAPE) {
System.out.println("fruit is " + Fruit.GRAPE);
} else {
System.out.println("fruit is not " + Fruit.GRAPE);
}
}

注解Annotations (Metadata) 便于编译器在编译期根据Metadata做各种各样的校验;第三方框架或工具根据Metadata生成代码、文档等,实现DI等。比如:Override、Deprecated、SuppressWarnings
@StringAnnotation("Class")
public class AnnotationSample {

@StringAnnotation("Constructor")
public AnnotationSample() {
}

@StringAnnotation("Field")
public int n;

@StringAnnotation("Method")
public void function(
@StringAnnotation("Param1") int param1,
@StringAnnotation("Param2") int param2) {
}

public static void main(String[] args) {
Class clazz = AnnotationSample.class;

p("类", clazz.getDeclaredAnnotations());

Constructor[] cs = clazz.getConstructors();
p("构造函数", cs[0].getDeclaredAnnotations());

Field[] fs = clazz.getDeclaredFields();
p("成员变量", fs[0].getDeclaredAnnotations());

Method[] ms = clazz.getDeclaredMethods();
p("方法", ms[1].getDeclaredAnnotations());

Annotation[][] ma = ms[1].getParameterAnnotations();
p("参数1", ma[0]);
p("参数2", ma[1]);
}

public static void p(String message, Annotation[] as) {
System.out.println(message);
for (Annotation a : as) {
System.out.println(a);
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface StringAnnotation {
String value();
}

增强循环Enhanced for Loop
List<Integer> list = new ArrayList<Integer>();
list.add(2);

// 旧写法
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}

// 新写法
for (Integer value : list) {
System.out.println(value);
}

自动装解箱Autoboxing/Unboxing
List<Integer> list = new ArrayList<Integer>();
// 旧写法
list.add(new Integer(1));
int x = list.get(0).intValue();

// 新写法
list.add(2);
int y = list.get(1);

System.out.println("x = " + x);
System.out.println("y = " + y);

变参Varargs
public static void variableLengthArgument(String... args) {
for (String arg : args) {
System.out.println(arg);
}
}

静态引入Static Import
import static java.lang.Math.*;

public class StaticImportSample {

public static void main(String[] args) {
// 旧写法
System.out.println("cos(PI) = "+ Math.cos(Math.PI));
// 新写法
System.out.println("cos(PI) = "+ cos(PI));
}

}

并发库Concurrency Framework**********[url=http://www.amazon.com/dp/0321349601/]《Java Concurrency In Practice》[/url]

[b](8)Java SE 6(JDK6) (2006/12/11-2013/2) Mustang [url=https://jcp.org/en/jsr/detail?id=270]JSR 270[/url][/b]
语言本身变化不大

脚本语言支持Scripting Language Support
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
String script = "function hello (name) {return 'Hello,' + name;}";
engine.eval(script);
Invocable inv = (Invocable) engine;
String res = (String) inv.invokeFunction("hello", "Scripting");
System.out.println("res:" + res);

编译器接口Java Compiler API
public class CompilerAPISample {

public static void main(String[] args) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();

String src = "public class HelloWorld {"
+ "public static int main(String args[]) {"
+ "System.out.println(\"This is in another java file\");"
+ "return(1);" + "}" + "}";

JavaFileObject file = new JavaSourceFromString("HelloWorld", src);

String[] compileOptions = new String[] { "-d", "bin" };
Iterable<String> compilationOptionss = Arrays.asList(compileOptions);

Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
CompilationTask task = compiler.getTask(null, null, diagnostics, compilationOptionss, null, compilationUnits);

boolean success = task.call();
System.out.println("Success: " + success);

if (success) {
Object ret;
try {
Class<?> clazz = Class.forName("HelloWorld");
Method method = clazz.getMethod("main", new Class[] { String[].class });
ret = method.invoke(null, new Object[] { null });
System.out.println(ret);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
JavaSourceFromString(String name, String code) {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}

JAXB
public class JAXBSample {

public static void main(String[] args) {
Book book = new Book();
book.setAuthor("rensanning");
book.setTitle("Java New Feature");
book.setPages(88);

File file = new File("c://testJAXB.xml");
try {
JAXBContext ctx = JAXBContext.newInstance(Book.class);
Marshaller marshaller = ctx.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(book, file);
marshaller.marshal(book, System.out);

Unmarshaller unmarshaller = ctx.createUnmarshaller();
Book xmlBook = (Book) unmarshaller.unmarshal(file);

System.out.println(xmlBook);

} catch (JAXBException e) {
e.printStackTrace();
}
}

}
@XmlRootElement
class Book {
private String title;
private String author;
private int pages;
public String getTitle() {
return title;
}
@XmlAttribute
public void setTitle(String name) {
this.title = name;
}
public String getAuthor() {
return author;
}
@XmlElement
public void setAuthor(String author) {
this.author = author;
}
public int getPages() {
return pages;
}
@XmlElement
public void setPages(int pages) {
this.pages = pages;
}
@Override
public String toString() {
return "Book [title=" + title + ", author=" + author + ", pages=" + pages + "]";
}
}

其他
public class HTTPServerSample {

public static void main(String[] args) throws IOException {
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
server.createContext("/sample", new SampleHandler());
server.setExecutor(null);
server.start();
}

}
class SampleHandler implements HttpHandler {
public void handle(HttpExchange exchange) throws IOException {
String response = "Hello World";
exchange.sendResponseHeaders(200, response.length());
OutputStream ost = exchange.getResponseBody();
ost.write(response.getBytes());
ost.close();
}
}

public class ArrayCopySample {

public static void main(String[] args) {
// 前几项
final String[] original = {"Java", "Scala", "F#", "C#", "Haskell", "Python"};
final String[] first3 = Arrays.copyOf(original, 3);

// 任意区间
final int[] original2 = {0, 10, 20, 30, 40, 50};
final int[] range = Arrays.copyOfRange(original2, 3, 5);
}

}


[b](9)Java SE 7(JDK7) (2011/7/28-2015/4) Dolphin [url=https://jcp.org/en/jsr/detail?id=336]JSR 336[/url][/b]
二进制字面量和数字字面量下划线支持Binary Literals, Underscores in Numeric Literals
byte b = 0b010101;
short s = 0b010101010101;
int i = 0B010101010101010101010101;
long l = 0B0101010101010101010101010101010101010101L;

byte bb = 0b0101_0101;
short ss = 0x1F_2E;
int ii = 1_234_567_890;

switch中支持字符串Strings in switch Statements
String text = "ren";
switch (text) {
case "zhang":
System.out.println("zhang");
break;
case "ren":
System.out.println("ren");
break;
default:
System.out.println("none");
break;
}

同时捕获多个异常处理Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking
public class MultiCatchSample {

public static void main(String[] args) throws Exception {
multiCatch();
System.out.println("-------------------");
rethrow("aaa");
}

public static void multiCatch() {
try {
Field field = String.class.getField("equals111");
System.out.println(field);
// 多个异常时用竖线隔开
} catch (NoSuchFieldException | SecurityException e) {
e.printStackTrace();
}
}

public static void rethrow(String name) throws NoSuchFieldException,
SecurityException {
try {
if (name.equals("First")) {
throw new NoSuchFieldException();
} else {
throw new SecurityException();
}
} catch (Exception e) {
// 捕获后原封不动在throw
throw e;
}
}
}

泛型实例创建的类型推断Type Inference for Generic Instance Creation Diamond Syntax
// 旧写法
List<String> oldList = new ArrayList<String>();
Map<String, Long> oldMap = new HashMap<String, Long>();
List<Map<String, Long>> oldListMap = new ArrayList<Map<String, Long>>();

// 新写法
List<String> newList = new ArrayList<>();
Map<String, Long> newMap = new HashMap<>();
List<Map<String, Long>> newListMap = new ArrayList<>();

自动资源管理The try-with-resources Statement
public class TryWithResourcesSample {

public static void main(String[] args) {
// 多个可以用逗号隔开
try (MyFileReader auto1 = new MyFileReader();
MyFileReader auto2 = new MyFileReader()) {
System.out.println("Processing!");
} catch (Exception e) {
e.printStackTrace();
}
}

}
class MyFileReader implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("Close!");
}
}

对动态语言的支持Support fro Dynamic Language(InvokeDynamic)
MethodHandles.Lookup lookup = MethodHandles.lookup();
String name;
MethodType methodType;
MethodHandle methodHandle;

// Lookup invoke dynamic
methodType = MethodType.methodType(String.class);
methodHandle = lookup.findVirtual(Employee.class, "getName", methodType);
name = (String) methodHandle.invokeExact(new Employee());
System.out.println("invoke dynamic " + name);

// Lookup reflection
Method method = Employee.class.getMethod("getName", new Class[]{});
name = (String) method.invoke(new Employee());
System.out.println("reflection " + name);

NIO2**********[url=http://www.amazon.com/dp/1430240113/]《Pro Java 7 NIO.2》[/url]
public static void nio2Directory() throws Exception {
DirectoryStream<Path> stream = Files.newDirectoryStream(
Paths.get("c://"), new DirectoryStream.Filter<Path>() {
@Override
public boolean accept(final Path entry) throws IOException {
return !Files.isDirectory(entry);
}
});
for (Path p : stream) {
System.out.println(p.getFileName());
}
}

public static void nio2Files() throws Exception {
Path sampleFilePath = Paths.get("sample.txt");
if (!Files.notExists(sampleFilePath)) {
return;
}
sampleFilePath = Files.createFile(Paths.get("sample.txt"));
String content = "line1\nline2\n";
Files.write(sampleFilePath, content.getBytes());
for (String line : Files.readAllLines(sampleFilePath,
Charset.defaultCharset())) {
System.out.println(line);
}
System.out.println(Files.deleteIfExists(sampleFilePath));
}


[b](10)Java SE 8(JDK8) (2014/3/18-2017/3) [url=https://jcp.org/en/jsr/detail?id=337]JSR 337[/url][/b]
[list][*]Lambda表达式Lambda Expressions [url=http://rensanning.iteye.com/blog/2039106]详细内容[/url]
[*]默认方法、函数式接口、方法引用Method References、Default Methods、Type Inference [url=http://rensanning.iteye.com/blog/2037246]详细内容[/url]
[*]流Stream [url=http://rensanning.iteye.com/blog/2035551]详细内容[/url]
[*]新日期时间接口Date and Time API [url=http://rensanning.iteye.com/blog/2034622]详细内容[/url][/list]

[b](11)Java SE 9 (2017?)[/b]
Jigsaw:模块化JDK
Kulla:REPL (JShell)
接口private method
......
[url=http://www.journaldev.com/13121/java-9-features-with-examples#http2-client]Java 9 Features with Examples[/url]

[b]关于Java的interface[/b]
最开始只能是public abstract method / public static final variable,所以方法或变量前不用写修饰符。
Java 8开始支持 public static method 和 public default method
Java 9开始支持 private static method 和 private method

[img]http://dl2.iteye.com/upload/attachment/0106/9798/33dd2a40-062f-362a-9b7a-f1885d9584b8.jpg[/img]
[img]http://dl2.iteye.com/upload/attachment/0106/9994/19505324-839f-3135-892a-58a8d528bba4.png[/img]

[b]Java版本命名:[/b]
[list]
[*]•Java Platform 1.1.X_YYY
[*]•J2SE 1.2.X_YYY
[*]•J2SE 1.3.X_YY
[*]•J2SE 1.4.X_YY
[*]•J2SE 5.X Update Y (5.0u22)
[*]•JavaSE 6 Update Y (6u45)
[*]•JavaSE 7 Update Y (7u76)
[*]•JavaSE 8 Update Y (8u40)
[/list]

[b]JVM实现:[/b]
[list]
[*]•HotSpot VM(Sun Microsystems公司开发)
[*]•JRockit VM(BEA Systems公司开发,针对Intel CPU和服务器,WebLogic Server中用)
[*]•IBM J9 VM
[*]•Dalvik VM
[*]•其他
[/list]
***Oracle收购BEA Systems和Sun Microsystems后就同时拥有了前两个VM。

[b]JDK的实现:[/b]
[list]
[*]•Sun Java(Oracle Java)
[*]•IBM JDK
[*]•OpenJDK
[/list]
***Eclipse中JDT (Eclipse Java development tools) 使用的的Java编译器不是OpenJDK也不是OracleJDK而是Eclipse自己做的ECJ (Eclipse Compiler for Java)。

[b]其他相关问题[/b]
[list]
[*]•Java 2:和JDK1.1区别从「Java 2 SDK 1.2.2_004」开始称Java2,Java 2(J2ME、J2SE、J2EE三个版本开始出现)。
[*]•Oracle收购Sun后把http://java.sun.com/重定向到http://www.oracle.com/technetwork/java/index.html以前很多文档都看不到了。
[*]•搜JDK的源码发现很多类已经找不到原来的作者了,它们被标记为“@author unascribed”,其中不乏我们常用的System、File、Thread、Socket、IOException、NullPointerException、FileNotFoundException等。
[/list]

[list][*]2006年11月 Java开源但是争议很大被称为半开源
[*]2007年11月5日 谷歌发布Android操作系统
[*]2010年1月 Oracle收购Sun
[*]2010年10月 乔布斯宣布Apple不再支持Java[/list]

参考:
http://en.wikipedia.org/wiki/Java_(programming_language)
http://docs.oracle.com/javase/specs/
http://oracle.com.edgesuite.net/timeline/java/
http://docs.oracle.com/javase/8/docs/technotes/guides/language/enhancements.html
http://javapapers.com/core-java/java-features-and-history/
http://javapapers.com/core-java/java-history/
http://www.ne.jp/asahi/hishidama/home/tech/java/uptodate.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值