programming_language
Author: Cay S. Horstmann
Volumn I - Fundamentals, Ninth Edition
before the notes:
From C++ to Java there are a lot of details that need to be paid attention to. And this book explains them quite clearly.
Double.isNaN(x)
char
unless there is actual need to manipulate UTF-16 code units. Variable names are case-sensitive.
The length of variable names are unlimited.
In Java, no declaration is seperated from definition.
e.g. such things like extern int i
will not happen in Java.
use the key word final
to denote a constant.
use static final
inside a class to denote a class constant.
+, -, *, /, +=
++, --
==, !=
&&, ||
? :
bitwise operators: & | ^ ~
math functions and constants:
Math.sqrt(x)
Math.PI
without loss precision:
byte---short---int---long/double
char---int
with loss precision:
int---float
long---double
long---float
When two values are combined with a binary operator, both operands need to be converted.
double
or float
or long
, the other one will be converted into the same type. int
. the same as C++
int x = (int)9.9;
Boolean type can not be cast into any numeric type.
an alternative to conversion: b ? 1 : 0
String str = "hello";
methods
String substring(int beginIndex, int endIndex)
get the range of [beginIndex, endIndex) String substring(int beginIndex)
+
str.equals(another_string)
"hello".equals(str)
is valid. str.equalsIgnoreCase()
null
, use if(str==null)
. null
is different from empty string "" with the length of zero. str.length()
method yields the number of code units(char) required to make up the string object. str.codePointCount(0,str.lenth())
int codePointAt(int index)
return the code point that starts or ends at certian location. str.charAt(n)
return the code unit at position n which begin at 0, but it is too low-level. Do not use it. int offsetByCodePoints(int startIndex, int cpCount)
int str.compareTo(String other)
str
comes before other
in dictionary order and a positive if str
comes after other
, or 0 when the two are equal.boolean endsWith(String suffix)
boolean startWith(String prefix)
int indexOf(String str)
int indexOf(String str, int fromIndex)
int inedxOf(int cp)
int inedxOf(int cp, int fromIndex)
Strin replace(String oldString, String newString)
oldString
with newString
. String toLowerCase()
String toUpperCase()
String trim()
eliminates all leading and trailing spaces Building Strings
use StringBuilder
class
StringBuilder builder = new StringBuilder();
builder.append("abc");
String str = builder.toString();
char*
pointer rather than char[]
in C programming and similar to string
objects in C++ programming, whose memory management is performed by constructors, assignment operators and destructors. But C++ strings are mutable with every char inside modifiable. scanner
that is attached to System.in Scanner in = new Scanner(System.in);
String line = in.nextline()
next()
nextIn()
nextDouble()
etc. boolean hasNext()
boolean hasNextInt()
To read a password, there is a little different.
Console cons = System.console(); // a console object for interaction
String name = cons.readline("User name: ");
char[] password = cons.readPassword("Password: ");
// for security reason, returns an array rather than a string.
Formatting output
System.out.print()
Java SE 5.0 brings this from the C library:
System.out.printf("%d, %.5f", age, salary);
Similar use in constructing a String:
String str = String.format("%d, %.5f", age, salary);
printf("%tc", new Date());
There are many different formats to print a date. $
is used to specify the index(start from 1, not 0) of the argument to be formatted. printf("%2$d, %1$tc, %2$f", date, salary);
<
is used to indicate the same argument as the previous. printf("%ty, %<tm, %<td", new Date());
File Input & Output
Scanner in = new Scanner(Paths.get("myfile.txt"));
Do not directly put a String as Scanner's parameter.
The file should be located in the relative directory of where JVM starts. To see it, use System.getProperty(user.dir)
. Otherwise, use an absolute directory like C:\\User\\lenovo
.
PrintWriter out = new PrintWriter("myfile.txt");
If the file is not found, it will be created.
Mostly they are identical to C++ or C, but there are slight differences.
The same things: if, while, for, switch
goto
, but a labeled break
. in java.math package, use BigInteger
and BigDecimal
(floating-point).
static BigInteger valueOf(long x)
BigInteger add(BigInteger other)
the same as substract, multiply, divide, mod int compareTo(BigInteger other)
do the substract to get the resultAttention: Java does not allow programmable operator overloading. So you cannot use + or - to big numbers.
An array is a date structure that stores a collection of values of the same type. You can access through index like a[1]
.
definition
int[] a = new int[100];
which is similar to int* a
in C++
int a[]
is also valid but not recommended.
initialization
When you created an array of numbers/boolean/objects, all elements are initialized with 0/false/null.
(null means it does not hold any object.)
Different ways of initialization:
int[] a = {1,2,3};
int[] a = new int[]{1,2,3};
An array with the length of zero is OK, but it is not null.
for-each loop
for(type variable: collection) statement
sets the given variable to each element of the collection and excecute the statement.
The collection must be an array or objects of a class that implements the Iterable
interface.
String array in command-line parameters
public static void main(String[] args)
receives an array of Strings specified in the command line.
call the program with the following command:
java class_name -q one two
Then -q
, one
and two
are args[0], args[1] and args[2] respectively.
Methods
toString()
returns a string like "[1, 2, 3, 4]"
Array.copyOf(type[], int length)
for deep copy Array.copyOf(type[], int start, int end)
static void sort(type[] array)
static int binarySearch(type[] a, int start, int end, type v)
static void fill(type[] a, type v)
static boolean equals(type[] a, type[] b)
Multidimensional Array
double[][] a = new double[row][col];
double[][] b = {{1,2},{3,4}};
access by two pairs of brackets [][]
for(double[] row: a){
for(double value: row)
...
}
Array.deepToString(b)
"[[1,2],[3,4]]"
double** a = new double*[row];
for(int i=0;i<row;i++)
a[i] = new double[col];
Niklaus Wirth, the designer of Pascal language said,
Algorithm + Data structure = Programs
This is the traditional understanding of programming, algorithm first and then data structure. But in object-oriented programming, data comes first, and then look at the algorithms.
Three things about an object:
Nouns are class. Verbs are methods.
More commonly, experience-based.
UML notation
An object variable does not contain an object. It only refers to an object.
Java object variables are analogous to C++ object pointers.
Date birthday; // Java
is the same as
Date* birthday; // C++
accessor: get methods
mutator: set methods
One source file has only one public class and any number of nonpublic class. The name of the source file must match that of the public class.
The compiler will create .class
file for each class.
Recommendation: make all instance field private, except for public final fields.
A constructor
new
operatorOne of the common error for C++ programmer to code in Java is forgetting the new
when creating an object.
Be careful not to introduce local variables inside constructors with the same name as instance fields.
Explicit parameters are explicitly listed in the declearation of the method, while the implicit one is the object of type that appears before the method name.
The key word this
can be used to refer to the implicit parameter.
Unlike C++, all methods of Java classes are defined inside the class. JVM decides which method is inline.
To get and set the value of an instance field, we need
If an accessor wants to return references to mutable objects, it should be cloned first by .clone()
method. Otherwise encapsulation will be breaken.
Access privileges are class-based, not instance-based.
Therefore, a method can access the private data of all objects of this class.
Final instance fields must be initialized when the object is constructed. Having set the final field value must be guaranteed after the end of every constructor.
If an object variable is declared as final, it does not mean that the object itself is constant but the object reference that stored in the variable does not change after construction.
If a field is defined static
, then there is only one such field per class.
Static variables are rare. Static constants are more common.
And public constants are OK because no one can modify.
public static final
Static methods are used in two situations:
The main method does not operate on any object. Every class can have a main method. It is a handy trick for unit testing.
Java always uses call by value.
Methods get a copy of all parameter values passed to it and cannot modify the contents of any parameter variables.
A method
Constructors can be overloaded.
Default field initialization.
There is a free no-argument constructor only when my class has no other constructors.
explicit field initilization
simply assign a value in the class definition
This assignment will be carried out before the constructor.
construtor calls constructor
If the first statement of a constructor has the form of this()
, it calls another constructor of the same class.
It never happends in C++.
initializatino blocks
set assingment statements of fields inside a block
denote static
before the block if initialization is complex.
not common
order of initialization
Java does automatic garbage collection.
A finalize
method will be called before it. But do not rely on it for resource recycling.
Instead, supply a close
method that does the cleanup.
A package is a collection of classes.
The standard Java package is inside the java and javax package hierachies.
The main reason for using package is to guarantee the uniqueness of class names. Classes in different packages can have the same name.
To guarantee the uniqueness of package name, use your domain name in reverse.
There is no relationship between nested packages.
A class can use all classes from its own package and all public classes from other package.
To access classes from other packages, use its full name or use import
for short.
The package and import in Java is analogous to the namespace and using in C++, rather than #include.
import static
+ package_name
To use the static methods andd fields of the class without prefix
put the package statement at the top of the source file
package com.mycompany.corejave;
Otherwise, it will be in the default package.
To complile in the command line:
javac com/mycompany/corejave/wedget.java
java com.mycompany.corejave.wedget
The compiler looks for files, while the interpreter looks for classes, which accounts for the differ of their paths.
If the feature(class, method, variable) does not have public or private modifier, it is package-visible. Classes from the same package can access it. This will break encapsulation.
package sealing: no further classes can be added. (Chapter 10)
Class files can be stored in a JAR(Java Archive) file which contains multiple class files adn subdirectories in a compressed ZIP format.
To share classes among programmers,
1. Place class files inside a directory.
2. Place any JAR files inside another directory.
3. Set the class path - The base directory, the JAR file and the current directory (.)
The compiler always looks for files in the current directory. But JVM only looks into the current directory if the "." is on the class path.
ways for setting the class path:
1. using command java -classpath
+ the three paths
2. set CLASSPATH environment variable in different shells
Do not set CLASSPATH permanently!
javadoc
is a tool in JDK that generates HTML documentation from source files.
javadoc
looks for
The comment is placed above the feature it described.
Start with /**
, end with */
Tags start with @
You can use HTML modifiers.
Class Comments
must be placed after any import statements, before the class definition.
Method Comments
@param
variable_name discription@return
description@throws
class descriptionField Comments
Only need to document public field - static constants.
General Comments
@author
name@version
text @see
referencePackage Comments
supply an HTML file named package.html
and all text in its body will be extracted.
To generate documentation, run
javadoc -d
docDirectory nameOfPackage1 nameOfPackage2 ...
using the key word extends
to inherite:
class SubClass extends SuperClass{ ... }
All inhetitance in Java is public inheritance.
Subclass has no direct access to the private field of the superclass.
A subclass can define method that overrides the same one in the superclass.
To call the superclass method from the subclass, use super.
method_name()
To call the superclass constructor from the subclass constructor: super(
parameter list );
In C++, we use class derived: public base{ ... }
to inheritate, base::method()
to call base methods, Derived(init_list): Base(init_list){ ... }
to construct the part of the superclass.
Polymorphism: An object variable can refer to multiple actual types.
Dynamic binding: Automatically select the appropriate method at runtime.
Dynamic binding is default in Java. You don't have to declare virtual
as C++.
Java does not support multiple inheritance. Use interface instead.
Overriding can change the return type of a method to a subtype of the orinal one.
The subclass method that overrides that of the superclass must be declared as public as well.
final
to ban inheritance final
method cannot be overrided. final
class cannot be extended. All methods in the class are final, but not the fields. instance of
is used to check before casting from superclass to subclass.
if(x instance of SubClass){ // false if x is null
SubClass sub = (SubClass)x;
}
// in c++
SubClass* sub = dynamic_cast<SubClass*>(x);
if(sub != NULL){
When a abstract class is extended, there are two choices:
In C++, a class is abstract if it has at least one pure virtual function such as virtual void f() = 0;
use with caution in fields
make more sense to methods
protected in Java is less safe than in C++, because
other classes in the same package can access it.
private
visible to the class onlypublic
visible to the worldprotected
visible to the package and all subclassesEvery class in Java extends Object.
In Java, only premitive types (numbers, characters and boolean) are not objects.
testing equality between a subclass and a superclass
two senarios:
getClass
test - x.equals(y)
returns true if and only if y.equals(x)
returns true. instanceof
test and allow objects of different subclasses to be equal to one another. The recipe for equals
method:
Object otherObject
. this
happens to be identical to otherObject.this
and otherObject. equals
can change in subclasses, use the getClass
test. instanceof
test. Object.equals
for objects. equals
in a subclass, include a call to super.equals
public boolean equals(Object otherObject){
// 2.
if(this == otherObject) return true;
// 3.
if(otherObject == null) return false;
// 4.
if(getClass() != otherObject.getClass()) return false;
// or
if(!(otherObject instanceof ClassName)) return false;
// 5.
ClassName other = (ClassName)otherObject;
// 6.
return field1 == other.field1
&& Object.equals(field2, other.field2)
&& ...;
}
The hashcode method is defined in the Object class.
If equals method is redefined, hashcode method needs to be redefined as well. And they must be compatible.
If two variables are equals under the equals method, they must have the same value of hash code.
Some relative methods:
int Object.hashcode()
returns the hash code for this object (returns 0 for null).
int Object.hash(Object...Object)
returns a combined hash code.
itn Array.hashcode(type[] a)
computes the hash code of array a with different components.
A common format for toString method:
getClass().getName()
followed by field values in square brackets. For derived classes, add square brackets after.
The toString method is invoked automatically when contatenating a string with an object by "+" operator ,or printing an object by System.out.println()
.
Specifically, to print an array, use Array.toString(a)
instead.
For a multimensional array, use Array.deepToString(a)
Adding a toString to a user-defined class is strongly recommended.
ArrayList is a generic class with a type parameter in angle brackets.
ArrayList is similar to the C++ vector template.
construction
ArrayList<Type> al = new ArrayList<Type>();
In Java 7, "diamond syntax" can omit the type parameter on the right.
ArrayList<Type> al = new ArrayList<>();
Or with initialized capacity:
ArrayList<Type> al = new ArrayList<>(100);
operations
boolean add(Type obj)
append, always return true.
int size()
void ensureCapacity(int capacity);
allocate an array with desired storage capacity
accessing elements
No [] syntax can be used.
Type get(int index)
void set(int index, Type obj)
Type remove(int index)
shifts down all element above and returns the removed element
warning
ArrayList has a "raw" version which takes no type paramters.
The "raw" one cannot be assigned or cast into a typed one.
The compliler would not check if you pass a typed ArrayList into a "raw" ArrayList and this is dangerous.
All primitive types have class counterparts.
They are called wrappers:
Integer, Long, Float, Double, Short, Byte, Character, Void, Boolean
Wrapper classes are immutable and final.
A typical usage is to construct an ArrayList of integer.
Angle brackets do not recieve primitive types.
use ArrayList<Interger> list = new ArrayList<>()
instead.
Autoboxing
list.add(3)
does autoboxing to be list.add(Integer.valueOf(3))
In most cases, the primitive types and their wrappers are likely to be the same except for their identity.
Wrappers are a convenient place to put some basic methods.
The word "boxing" is taken from C#.
int Integer.intValue()
return as an int
static String Integer.toString()
static int Integer.parseInt(String s, int radix)
returns the integer contained in a string. The integer should be in the given base or default 10 base.
static Integer Integer.valueOf(String s, int radix)
similar
public void f(int... list){ }
The ellipsis "..." is part of the code, which denotes the method receives an arbitary number of objects, and is exactly the same as Object[]
. So for(int x: list)
can be used for iteration.
To call the method, use f(1,2,3);
.
Enumeration is actually a class with a fixed number of instances.
public enum MyEnum{SMALL, MEDIAN, LARGE };
The Reflection Library provides tools for manipulating Java codes dynamically. A program that can analyze the capabilities of classes is called reflective.
It is a powerful and complex mechanism.
However, it is useful in system programming or toolkit design, not in applications.
The Java runtime system maintains runtime type identification on all objects, which keeps track on the class which each object belongs to.
class cl = x.getClass();
getName()
method is commonly used, but it works strange for array types (historical reason).To obtain a class object by its name
Class cl = Class.forName("java.util.Date");
Or simply
Class cl = Date.class;
You can use "==" to compare class objects.
x.getClass().newInstance();
, which non-parameter constructor will be invoked. (cannot pass any parameters)Using "try-catch" statement to catch exceptions.
The compiler will tell you which method need to supply a handler.
The three classes Field
, Method
, Constructor
in Java.lang.reflect package describe three aspects of the class respectively.
getName
returns a name
getModifier
returns an integer
Modifier.isPublic/isPrivate/...
analyze the integer, return boolean
Field.getType
getFields
, getMethods
, getConstructors
return arrays of the public fields, methods and constructors.
getDeclaredFields
, getDeclaredMethods
, getDeclaredConstructors
return all, not just public ones.
access field information by the get
method of the Field
class
MyClass mc = new MyClass();
Class cl = new mc.getClass();
Field f = cl.getDeclaredField("field_name");
Object obj = f.get(mc);
// returns an object whose value is the current value of the field of mc
This method can only be used to access accessible fields. If the field is private, you can change its accessibility by setAccessible
method on a Field
, Method
, Constructor
object.
f.setAccessible(true);
As for number objects, get()
does autoboxing.
Also, we can set value by set
method
void Field.set(Object obj, Object newValue);
customize your own generic toString method used for all objects
Consider we are coding the implementation of the copyOf
method of a geneic array that holds elements of any type.
Any object can be converted into Object
class, but it would not help because an array of elements of Object
class would not be cast back into the same type of array after the memory reallocation.
Therefore we would not cast an instance of MyClass[]
into Object[]
class. Rather, we treat the instance of MyClass[]
as an Object and create a new array using reflect.Array.newInstance()
based on this Object.
public static Object copyOf(Object obj, int newLength){
Class cl = obj.getClass();
if(!cl.isArray()) return null;
Class componentType = cl.getComponentType();
int length = Array.getLength(cl);
Object newArray = Array.newInstance(componentType, newLength);
System.arraycopy(obj, 0, newArray, 0, Math.min(length, newLength));
return newArray;
}
int[] a = {1,2,3,4};
a = (int[])copyOf(a, 10);
Java has no method pointer because the designer thought it is dangerous and Java interface is an alternative.
Howeverm the reflection mechanism allows you to call arbitrary methods. Yet In a mush slower way.
Method
object Method getMethod(String name, Class... parameterTypes)
Method m = x.class.getMethod("method_name",int.class);
invoke
method Object invoke(Object obj, Object... args)
Suggestion: use method class only when absolutely necessary.
Two advanced techniques:
A interface is a set of requirements for the classes that want to conform to the interface.
For instance, if the sort method of Array class needs to be used to sort an array of objects, these objects must belong to classes that implement the Comparable interface which has a method called compareTo.
public
. public static final
.
public interface MyInterface{
void f(); # not necessarily public
double pi = 3.14; # auto public static final
}
implements
.in Java SE 5.0, an interface can be generic.
public interface MyInterface<T>
class MyClass implements MyInterface<MyType>
new
an interface. MyInterface x;
instanceof
can also be used to check whether an object implements an interface. if(obj instanceof MyInterface)
extends
another interface. This will build an hierachy from generlization to specialization. public interface YourInter extends MyInterface{
class MyClass implements MyInter, YourInter{
The introduction of interfaces in Java aims to replace multiple inheritance.
The clone
method is declared protected
in the Object
class so you cannot simply call obj.clone().
When you decide to clone an object, decide:
1. The default clone method is good enough.
2. The default clone method can be patched up by calling clone on the mutable subobjects to avoid shallow copy.
3. cancel the cloning.
To choose either the first or the second choice, a class must:
1. implement the Cloneable
interface.
2. redefine the clone
method with publc modifier.
The Cloneable
interface has nothing to do with the clone
method which is inherited from Object
class. It just serves as a tag to inform programmers. ("marker interface") But this is acutally a bad use.
class MyClass implements Cloneable{
public MyClass clone() throws CloneNotSupportedException
{
MyClass myClone = (MyClass)super.clone();
// deep copy if necessary
myClone.fields = (Type)fiels.clone();
return myClone;
}
}
Specially, all array types have a public
clone method instead of protected.
Cloning is less common than you think.
"Object serialization" is an alternative for cloning objects.
The callback pattern specifies the actions that should occur whenever a particular event happens.
For example, a timer wants to invoke an event after a ccertain time interval. The event is a class. The invoker is an interface with a method that takes the event as a parameter. And the listener implements this interface and supply the detail to invoke the event. Finally, the listener is passed to the timer as a parameter.
Whenever you would use a function pointer in C++, you should use an interface in Java.
An inner class is a class that is defined inside another class.
In C++, nested classes provide two benefits: name control (call the inner class with the name of outer class) & access control (classes in the private part are hidden from outside).
OuterClass.this
. OuterClass.this.field
.InnerClass m = OuterClass.new InnerClass();
OuterClass.InnerClass
. The inner class is a phenomenon of the compiler.
The compiler translates the inner classes into nomal classes by concatenating the name of the outer class before them.
JVM knows nothing about inner classes.
An inner class inside a method is called a local inner class.
Local classes are never declared with an access modifier.
Their scope is restricted to the block in which they are declared.
One great advantage: it is totally hidden from the outside. No one except the method has any idea of the inner class.
Local inner classes can access local final variables.
The inner class stores a copy of the local final varibles of the outer class when being constructed. So it is possible that the local final variable will be called by an object of the inner class even after the method ends.
Without names.
new SuperType(construction parameters){
//inner class methods and data
}
Noted that SuperType
can be an interface or a super class.
A inner class that is static
does not have a reference to the outer class.
Only inner classes can be declared static.
Use a static inner class whenever the inner class does not need to access an outer class object.
Inner classes that are declared inside an interface are automatically static and public.
use proxy when creating new classes that implements a set of interfaces that I do not know which to choose at compile time
A invocation handler is an object of any class that implements the InvocationHandler
interface which has a single method invoke
.
To create a proxy object, use the newProxyInstance
method of the Proxy
class.
We define different handlers for proxies with different purposes.
Proxy
.Proxy
superclass.Proxy is an advanced technique for tool builders, not for application programmers.