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

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

(0)Java由来
  • 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)  https://www.youtube.com/watch?v=1CsTH9S79qI
  • 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写的。


(1)JDK Alpha and Beta (1995)
  • 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
(2)Java 1.0(JDK1.0) (1996/01/23) Oak
Sun的slogan“Write once, run anywhere”,但最开始Java存在大量问题,变成了“Write once,debug everything”。同时期(95-96)的语言还有:JS、Ruby、PHP、Delphi、ColdFusion、OCaml、Ada95。

(3)Java 1.1(JDK1.1) (1997/02/19) Sparkler
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)
引用
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

// 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;
	}
}


(4)J2SE 1.2(J2SDK1.2) (1998/12/08) Playground
集合框架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********** 《Java Swing》

(5)J2SE 1.3(J2SDK1.3) (2000/05/08) Kestrel
动态代理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();


(6)J2SE 1.4(J2SDK1.4) (2002/2/6-2008/10)  Merlin JSR 59
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*********** 《Java NIO》
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);


(7)J2SE 5.0(JDK5.0) (2004/9/30-2009/10)  Tiger JSR 176
泛型Generics********** 《Java Generics》
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********** 《Java Concurrency In Practice》

(8)Java SE 6(JDK6) (2006/12/11-2013/2)  Mustang JSR 270
语言本身变化不大

脚本语言支持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);
	}

}


(9)Java SE 7(JDK7) (2011/7/28-2015/4)  Dolphin JSR 336
二进制字面量和数字字面量下划线支持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********** 《Pro Java 7 NIO.2》
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));
}


(10)Java SE 8(JDK8) (2014/3/18-2017/3) JSR 337

(11)Java SE 9 (2017?)
Jigsaw:模块化JDK
Kulla:REPL (JShell)
接口private method
......
Java 9 Features with Examples

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




Java版本命名:
  • •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)


JVM实现:
  • •HotSpot VM(Sun Microsystems公司开发)
  • •JRockit VM(BEA Systems公司开发,针对Intel CPU和服务器,WebLogic Server中用)
  • •IBM J9 VM
  • •Dalvik VM
  • •其他

***Oracle收购BEA Systems和Sun Microsystems后就同时拥有了前两个VM。

JDK的实现:
  • •Sun Java(Oracle Java)
  • •IBM JDK
  • •OpenJDK

***Eclipse中JDT (Eclipse Java development tools) 使用的的Java编译器不是OpenJDK也不是OracleJDK而是Eclipse自己做的ECJ (Eclipse Compiler for Java)。

其他相关问题
  • •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等。


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

参考:
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

猜你喜欢

转载自rensanning.iteye.com/blog/2195622