Good about Java:html
friendly syntax, memory management[GC can collect unreferenced memory resources], object-oriented features, portability.java
Stackapp
Stores method invocations, local variables(include object reference, but the object itself is still stored in heap).less
If you look at the stack trace, the top method is the one being called, and once it is finished, it will be removed out of the stack.socket
Heapide
Stores all objects(include instance variables in the class).ui
.hashcode() returns the memory address of the object, so no same hashcode for two objects.this
But when the Class is value object, you could override .hashcode() and .equals().編碼
Constructorspa
Default parameterless constructor: only generated by compiler when there is no your constructor.
Parent constructor: if parent class has default constructor, compiler will automatically call it without .super(). But if not, or you want to call the parent constructor with parameters, you need to call .super() explicitly.
Overloaded constructor: use .this(...) at the first line.
File I/O
There are two streams: Character stream & Binary stream
Character stream: to read/write human readable files, like .txt .xml .html
Class: FileReader/Writer[extends InputStreamReader, 缺點:使用系統默認字符字節編碼方式], more advanced: BufferedReader/Writer
Binary stream: to read/write machine readable files, like .exe .class .obj
Class: FileInput/OutputStream, more advanced for Object: ObjectInput/OutpoutStream(.writeObject() method).
FileInputStream是最基本的,只能讀出來Byte,而Wrapper class DataInputStream高級一些,能夠讀出來各類primitive types。ObjectInputStream另有readObject()。若是你想讀出來String, 那麼使用InputStreamReader[優勢:能夠指定字符字節編碼方式].
InputStreamReader
(and its father Reader
) are used specifically to deal with characters (so strings) so they handle charset encodings (utf8, iso-8859-1, and so on) gracefully.
Example:
// 讀取字節轉換成字符
String charset = "US-ASCII";
FileInputStream inputStream = new FileInputStream(file);
InputStreamReader reader = new InputStreamReader(inputStream, charset);
StringBuffer buffer = new StringBuffer();
char[] buf = new char[64];
int count = 0;
try {
while ((count = reader.read(buf)) != -1) {
buffer.append(buffer, 0, count);
}
} finally {
reader.close();
}
讀寫file要注意的: new FileReader(filename)會throw FileNotFoundException(extends IOException),bufferedReader.readLine()會throw IOException,最後別忘記bufferedReader.close()。讀寫file更好的方法是用InputStreamReader(new FileInputStream(filename)),由於FileReader
does not allow you to specify an encoding and instead uses the plaform default encoding, which makes it pretty much useless as using it will result in corrupted data when the code is run on systems with different platform default encodings.
Immutable Class
Instance could not be modified. 這就保證了當前線程用到的immutable object不會被其它線程修改。
How to: private final fields, final class, no setter methods, ensure exlusive access to mutable components.
String
StringBuilder不是thread-safe的,而StringBuffer因爲有synchronized methods因此是thread-safe的。
ClassLoader
JVM有Bootstrap(核心類庫), Extensions(擴展類庫), System Class Loaders,App classloader(CLASSPATH類),會load不少classes before loading包含main()的class。
程序的開始是main(String[] args), 由此開始由Class loader來load用到的class。
一個classloader只能load同一個class一次,而同一個class能夠由不一樣的classloaders來load。
A software library is a collection of related object code. In the Java language, libraries are typically packaged in JAR files. Libraries can contain objects of different types. The most important type of object contained in a Jar file is a Java class. A class can be thought of as a named unit of code. The class loader is responsible for locating libraries, reading their contents, and loading the classes contained within the libraries. This loading is typically done "on demand", in that it does not occur until the class is actually used by the program. A class with a given name can only be loaded once by a given classloader.
Even building a JAR file from the class files doesn't change this -- the JAR is just a container for the class files.
The initial set of class loads are all triggered by the attempt to load the 起始class. These are the core classes that are used by every Java program, no matter how small. 而後開始load 當前class用到的class, recursively.
A lot happens inside the JVM when a class is loaded and initialized, including decoding the binary class format, checking compatibility with other classes, verifying the sequence of bytecode operations, and finally constructing a java.lang.Class
instance to represent the new class.
Sockets
In UDP, as you have read above, every time you send a datagram, you have to send the local descriptor and the socket address of the receiving socket along with it. Since TCP is a connection-oriented protocol, on the other hand, a connection must be established before communications between the pair of sockets start. So there is a connection setup time in TCP.
Client:
Socket MyClient; try { MyClient = new Socket("Machine name", PortNumber); } catch (IOException e) { System.out.println(e); }
Server:
ServerSocket MyService; try { MyServerice = new ServerSocket(PortNumber); } catch (IOException e) { System.out.println(e); }
Socket clientSocket = null; try { serviceSocket = MyService.accept(); } catch (IOException e) { System.out.println(e); }
Input at Client side:
DataInputStream input; try { input = new DataInputStream(MyClient.getInputStream()); } catch (IOException e) { System.out.println(e); }
Input at Server side:
DataInputStream input; try { input = new DataInputStream(serviceSocket.getInputStream()); } catch (IOException e) { System.out.println(e); }
Output at Client side:
PrintStream output; try { output = new PrintStream(MyClient.getOutputStream()); } catch (IOException e) { System.out.println(e); }
Passing parameter
Java is always passing by value. Value means copy of primitive variable, or copy of object reference[pointing to the same object].
So the original variable is not changed, in the method there will be a copy, but if you set the object, it will change the object content.
Why arguments passed to an anonymous inner class have to be final?
若是你pass local variables to anonymous class, 那麼噹噹前method退出的時候這些local var會被stack清除,而你的anonymous class object若是再想access這些fields就會報錯。因此,若是你把這些local var定義爲final,那麼JVM compiler就把它們變成了constants,以後再access這些fields就不會有問題。
Boxing & Unboxing
Why do we need wrappers for primitive types?
So that a null value is possible, to include in a collection...
Boxing: auto from primitive to Wrapper class. Unboxing: vice versa, but can throw NullPointerException, if Integer i = null; int x = i;
Public methods of java.land.Object class
.toString(), .hashCode(), .equals(), .clone(), .wait(), .notify(), .notifyAll(), .getClass()
What problems can be encountered when only overriding .equals() and not .hashcode()?
x.equals(y) does not mean they have same hashcode[default implementation], then it is not possible to use this type as a key in hashmap: because hashmap will first call .hashcode() and then .equals() when determining if the key is present in the map.
因此實際中你override了.equals()之後,必定要override .hashcode(),用同一套fields來calculate both methods.