欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-01 09:18:51
...
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写的。
20年Java发展历程(1995-2015)
            
    
    博客分类: Java  

(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

20年Java发展历程(1995-2015)
            
    
    博客分类: Java  
20年Java发展历程(1995-2015)
            
    
    博客分类: Java  

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
  • 20年Java发展历程(1995-2015)
            
    
    博客分类: Java  
  • 大小: 79.6 KB
  • 20年Java发展历程(1995-2015)
            
    
    博客分类: Java  
  • 大小: 238.6 KB
  • 20年Java发展历程(1995-2015)
            
    
    博客分类: Java  
  • 大小: 123.5 KB