第一章
1. Java可移植性(p5)
Java中的int永远为32位的整数。而在c/c++中,int可能是16位整数、32位整数,也可能是编译器提供商指定的其他大小。
2.Java与JavaScript(p12)
JavaScript的语法类似Java,除此之外,两者无任何关系。
第二章
1.SDK:Software Development Kit
2.设置执行路径(环境变量)时,如果想要保留Program Files目录,则要把整个路径用双引号引起来,如:“c:\Program Files\jdk1.7.0_02\bin";other stuff。
第三章
1.一个简单的Java应用程序
public class FirstSample
{
public static void main(String[] args)
{
System.out.println("we will not use 'Hello,World!'");
}
}
从类名FirstSample可以看出,标准的命名规范为:类名是以大写字母开头的名词,如果名字由多个单词组成,每个单词的第一个字母都应该大写(这种在一个单词中间使用大写字母的方式称为骆驼命名法。以其自身为例,应该写成CamelCase)。
2.main方法必须声明为public
在JavaSE1.4及以后的版本中将强制main方法是public的。
3.花括号的使用风格问题p31
4.println 与print
每次调用println都会在新的一行上显示输出
System.out还有一个print方法,它在输出之后不换行。
例如 System.out.print("Hello")打印“Hello”之后不换行,后面的输出紧跟在字符“o”之后。
5.从Java7开始,加上前缀0b就可以写二进制数。例如,0b1001就是9。另外,同样也是从Java7开始,还可以为数字字面加下划线,如用1_000_000(或者0b1111_0100_0010_0100_0000)表示一百万。这些下划线只是为了让人更容易读。Java编译器会去除这些下划线。
6.注意,Java没有任何无符号类型(unsigned)。
7.在c++中,数值和指针可以代替boolean值。值0相当于布尔值false,非0值相当于布尔值true。在Java中则不是这样。因此,Java应用程序员不会遇到下述麻烦:
if(x=0)// oops...meant x == 0
在c++中这个测试可以编译运行,其结果总是false。而在Java中,这个测试将不能通过编译,其原因是整数表达式x=0不能转换为布尔值。
8.在Java中,利用关键字final指示常量。
final double CM_PER_INCH = 2.54;
const是Java保留的关键字,但目前并没有使用。在Java中,必须使用final定义常量。
9.&&和 || 是按照“短路”方式求值的,如果第一个操作数已经能够确定表达式的值,第二个操作数就不必计算了。
10.Java中,>>>运算符将用0填充高位;>>运算符用符号位填充高位。没有<<<运算符。
在c/c++中,无法确定>>操作执行的是算术移位(扩充符号位)还是逻辑移位(高位填0)。Java消除了这种含糊性。
11.强制类型转换
强制类型转换的语法格式是在圆括号中给出想要转换的目标类型,后面紧跟待转换的变量名。
例如:
double x = 9.997;
int nx = (int) x;
这样,变量nx的值为9。强制类型转换通过截断小数部分将浮点值转换为整型。
如果想对浮点数进行舍入运算,以便得到最接近的整数,那就需要使用Math.round方法:
double x = 9.997;
int nx = (int)Math.round(x);
然而,调用round的时候,仍然需要使用强制类型转换(int)。
12.运算符优先级问题
由于&&的优先级比 || 的优先级高,所以表达式
a&&b || c
等价于
(a&&b) || c
又因为+=是右结合运算符,所以表达式
a+=b+=c
等价于
a+=(b+=c)
也就是将b+=c的结果(加上c之后的b)加到a上。
13.Java不使用逗号运算符。
14.定义枚举类型的目的:有时候,变量的取值只在一个有限的集合内(取值不绝对连续)。比如,星期一,二,三,四,五,六,七,没有零,也没有八,,更没有八点五。披萨饼只有小中大和超大四中尺寸。
15.每个用双引号括起来的字符串都是String类的一个实例;
16.子串
String类的substring方法可以从一个较大的字符串提取出一个子串。
例如:
String greeting = "Hello";
String s = greeting.substring(0, 3);
创建了一个由字符“Hel”组成的字符串。
注意的问题:
在substring中从0开始计数,直到3为止,但不包含3;
substring优点:容易计算子串的长度,字符串s.substring(a,b)的长度为b-a。例如,子串“Hel”的长度为3-0=3。
17.不可变字符串
String类没有提供修改字符串的方法,若要将greeting的内容“Hello”修改为“Help!”,
如果是c语言,没办法实现,但在Java中比较容易(拼接字符串)
greeting = greeting.substring(0,3) + "p!";
updated-2015年9月2日17:51:59
补:NULL C语言用大写
null Java用小写
1.Java中的格式化输出
Java SE 5.0沿用了C语言库函数中的 printf 方法。例如,调用
System.out.printf("%8.2f", x);
另外,还可以给出控制格式化输出的各种标志。
例如,逗号标志增加了分组的分隔符。即
System.out.printf("%,.2f", 10000.0/3.0);
打印
3,333.33
printf标志
标志 目的 举例
#(对于f格式) 包含小数点 3,333.
#(对于x或0格式) 添加前缀0x或 0 0xcafe
2.文件输入与输出
如果文件名中包含反斜杠符号,就要记住在每个反斜杠之前再加一个额外的反斜杠:
“c:\\mydirectory\\myfile.txt”
3.控制流程
Java没有goto语句,但break语句可以带标签,可以利用它实现从内层循环跳出的目的。
Java不允许在嵌套的块中重定义一个变量。(C语言可以)
4.循环
for循环
for语句的第一部分通常用于对计数器初始化;第二部分给出每次新一轮循环执行前要检测的循环条件;
第三部分指示如何更新计数器。
与c++一样,尽管Java允许在for循环的各个部分放置任何表达式,但有一条不成文的规则:for语句的三部分应该对同一个计数器变量进行初始化、检测和更新。
update 2015年9月4日17:19:40
1.for语句
(1) for(int i = 1; i <= 10; i++)
{
……
}
//i no longer defined here
(2)int i;
for(i = 1; i <= 10; i++)
{
……
}
//i is still defined here
2."通用for循环"(又被称为for each循环),这是 Java SE 5.0 新增加的一种循环结构。
例
for(int element : a )
System.out.println(element);
打印数组a的每一个元素,一个元素占一行
for each循环语句的循环变量将会遍历数组中的每个元素,而不需要使用下标值
3.switch语句的case标签
case标签可以是(类型)char、byte、short、或 int的常量表达式。
从Java SE 7开始,case标签还可以是字符串字面量。
例如:
String input = . . . ;
switch (input.toLowerCase( ) )
{
case "yes": //Ok since Java SE 7
. . .
break;
. . .
}
4.与c++不同,Java还提供了一种带标签的break语句,用于跳出多重嵌套的循环语句。
标签必须放在希望跳出的最外层循环之前。并且必须紧跟一个冒号。
示例:
……
read_data:
while(……)
{
for(……)
{
……
if(……)
break read_data;
//break out of read_data loop
……
}
}
5.数组
创建一个数字数组时,所有元素都初始化为0。boolean数组的元素会初始化为false。对象数组的元素则初始化为一个特殊值null,这表示这些元素(还)未存放任何对象。
String[ ] names = new String[10];会创建一个包含10个字符串的数组,所有字符串都为null。
在Java中,允许数组长度为0.
注意,数组长度为0与null不同。
Java中的 int[ ] a = new int [100]; 等同于c++中的int *a = new int[100];
Java中的[ ]运算符被预定义为检查数组边界,而且没有指针运算,即不能通过a加1得到数组的下一个元素;
在c++中,Java的声明double[ ][ ] balances = new double[10][6]; 等同于double**balances = new double*[10];(也就是说,分配了一个包含10个指针的数组)
然后,指针数组的每一个元素被填充了一个包含6个数字的数组:
for(i = 0; i < 10; i++)
balances[i] = new double[6];
注意:当创建new double[10][6]时,这个循环将自动执行。
当需要不规则的数组时,只能单独地创建行数组。
例如:
//allocate triangular array (分配)
int[ ][ ] odds = new int[NMAX+1][ ];
for(int n = 0; n <= NMAX; n++)
odds[n] = new int[n+1];
第4章 对象与类
类似构造对象的模板或蓝图。我们可以将类想象为制作小甜饼的切割机,将对象想象为小甜饼。
封装(encapsulation,有时称为数据隐藏)
所有的类源自于一个“神通广大的超类”------Object
通过扩展一个类来建立另外一个类的过程称为继承;
对象的改变必须通过调用方法实现。
Java中,使用构造器(constructor)构造新实例。构造器是一种特殊的方法,用来构造并初始化对象。
构造器的名字与类名相同。
new Date( ); Date 构造器,这个表达式构造了一个新对象
如果希望构造的对象多次使用,需将对象存放在一个变量中:
Date birthday = new Date( );
Date deadline; //定义了一个对象变量deadline;
//注意:一个对象变量并没有实际包含一个对象,而仅仅引用一个对象。
在Java中,任何对象变量的值都是对存储在另外一个地方的一个对象的引用
将对象变量设置为null,表明这个对象变量目前并没有引用任何对象。
Java的对象变量等同于c++的对象指针。
2.用户自定义类p106~107
注意:要想创建一个完整的程序,应该将若干类组合在一起,其中只有一个类有main方法。
在一个源文件中,只能有一个公有类。但可以有任意数目的非公有类。
3.构造器
构造器与类同名。在构造Employee类的对象时,构造器会运行。
构造器与其他的方法有一个重要的不同。构造器总是伴随着new操作符 的执行而被调用。
构造器没有返回值,可以有0个、1个或多个参数
4.(p119)每一个类可以有一个main方法。这是一个常用于对类进行单元测试的技巧。例如,可以在Employee类中添加一个main方法——如果想要独立地测试Employee类,只需要执行
java Employee
如果Employee类似一个更大型应用程序的一部分,就可以使用下面的语句运行程序
java Applicaton
并且Employee类的main方法永远不会执行。
5.方法参数(p121~124)
Java程序设计语言总是采用按值调用。方法得到的是所有参数值的一个拷贝。方法不能修改传递给它的任何参数变量的内容。
Java程序设计语言对对象采用的不是引用调用,实际上,对象引用进行的是值传递。
update 2015-9-17 13:05:54
6.重载(p126)
如果多个方法有相同的名字、不同的参数,便产生了重载。
7.初始化块(p131)
首先运行初始化块,然后才运行构造器的主体部分
可以使用Java编写一个没有main方法的“Hello,World”程序。
public class Hello
{
static
{
System.out.println("Hello,World");
}
}
当java Hello 调用这个类时,这个类就会加载,静态初始化块就会打印“Hello,World”
在此之后,会得到一个"main is not defined(没有定义)"错误信息。可以在静态初始化块的尾部调用System.exit(0)避免这一缺陷。
8.类路径p141
从java SE 6开始,可以在JAR文件目录中指定通配符,如下:
/home/user/classdir:.:/home/user/archives/'*'
9.类注释
类注释必须放在import语句之后,类定义之前。
第5章 继承
1.已存在的类称为超类(superclass)、基类(base class)或父类(parent class); 新类称为子类(subclass)、派生类(derived class)或孩子类(child class).
2.子类比超类拥有的功能更加丰富。
3.在设计类的时候,应该将通用的方法放在超类中,而将具有特殊用途的方法放在子类中。
4.子类可以提供一个新的方法来覆盖(override)超类中的这个方法:
5.this关键字有两个用途:一是引用隐式参数,二是调用该类其他的构造器。。
super关键字两个用途:一是调用超类的方法,二是调用超类的构造器。p153
6.重载(p126)
如果多个方法有相同的名字、不同的参数,便产生了重载。
7.初始化块(p131)
首先运行初始化块,然后才运行构造器的主体部分
可以使用Java编写一个没有main方法的“Hello,World”程序。
public class Hello
{
static
{
System.out.println("Hello,World");
}
}
当java Hello 调用这个类时,这个类就会加载,静态初始化块就会打印“Hello,World”
在此之后,会得到一个"main is not defined(没有定义)"错误信息。可以在静态初始化块的尾部调用System.exit(0)避免这一缺陷。
8.类路径p141
从java SE 6开始,可以在JAR文件目录中指定通配符,如下:
/home/user/classdir:.:/home/user/archives/'*'
9.类注释
类注释必须放在import语句之后,类定义之前。
第5章 继承
1.已存在的类称为超类(superclass)、基类(base class)或父类(parent class); 新类称为子类(subclass)、派生类(derived class)或孩子类(child class).
2.子类比超类拥有的功能更加丰富。
3.在设计类的时候,应该将通用的方法放在超类中,而将具有特殊用途的方法放在子类中。
4.子类可以提供一个新的方法来覆盖(override)超类中的这个方法:
5.this关键字有两个用途:一是引用隐式参数,二是调用该类其他的构造器。。
super关键字两个用途:一是调用超类的方法,二是调用超类的构造器。p153
update 2015年9月25日00:08:42
6.一个对象变量可以指示多种实际类型的现象被称为多态。在运行时能够自动地选择调用哪个方法的现象称为动态绑定。
7.is-a规则的另外一种表述法是置换法则。它表明程序中出现超类对象的任何地方都可以用子类对象置换。(p157)
例如:可以将一个子类的对象赋值给超类变量
Employee e;
e = new Employee(.....);
e = new Manager(......);
在java中,对象变量是多态的。一个Employee变量既可以引用一个Employee类对象,也可以引用Employee类的任何一个子类的对象(例如Manager、Secretary)。
但是,不能将一个超类的引用赋给子类变量。(也就是说,小的可以赋值给大的,大的不可以赋值给小的)
8.方法的名字和参数列表称为方法的签名。如:f(String)和f(int)具有相同的名字,不同签名的方法。
9.类中的特定方法可以被声明为final,这样,子类就不可以覆盖这个方法(final类中的所有方法自动地成为final方法)
class Employee
{
……
public final String getName()
{
return name;
}
……
}
10.抽象类(p164--p165)
类即使不含抽象方法,也可以将类声明为抽象类。
抽象类不能被实例化。如果将一个类声明为abstract,就不能创建这个类的对象。(但可以创建一个具体子类的对象)
11.受保护访问
protected
java中的protected概念要比c++中的安全性差。
12.Java用于控制可见性的4个访问修饰符:(p169)
1)仅对本类可见---private。
2)对所有类可见---public。
3)对本包和所有子类可见----protected。
4)对本包可见---默认,不需要修饰符。
13.在Java中,只有基本类型不是对象,例如数值、字符和布尔类型的值都不是对象。所有的数组类型,不管是对象数组还是基本类型的数组都扩展于Object类。
Employee[] staff = new Employee[10];
obj = staff; //ok
obj = new int[10]; //ok
14.toString方法 p175
随处可见toString方法的主要原因是:只要对象与一个字符串通过操作符"+"连接起来,Java编译就会自动地调用toString方法,以便获得这个对象的字符串描述。
例如
Point p = new Point(10, 20);
String message = "The current position is " + p;
//automatically invokes p.toString()
注意:在调用x.toString()的地方可以用""+x替代,这条语句将一个空字符串与x的字符串表示相连接。(x如果是基本类型,这条语句依然可以执行)。
如果x是任意一个对象,并调用
System.out.println(x);
println方法就会直接调用 x.toString(),并打印输出得打的字符串。
注意:数组有点不一样。数组要调用静态方法Arrays.toString。
例如
int[] luckyNumbers = {2, 3, 5, 7, 11, 13};
String s = Arrays.toString(luckyNumbers);
将生成字符串"[2, 3, 5, 7, 11, 13]"。
而要想打印多维数组(数组的数组)则需要调用 Arrays.deepToString方法。
15.泛型数组列表 p181
在Java中有一个被称为ArrayList的类,它使用起来有点像数组,但在添加或删除元素的时候,具有自动调节数组容量的功能。 ArrayList---泛型类。ArrayList<Employee> staff = new ArrayList<Employee>();
在Java 7中,可以省去右边的类型参数。
ArrayList<Employee> staff = new ArrayList<>();
注意:JavaSE 5.0以前的版本没有提供泛型类。
如果数组列表(ArrayList)的内部已经满了,数组列表就将自动地创建一个更大的数组,并将所有的对象从较小的数组中拷贝到较大的数组中。
如果可以估计数组的元素数量,可以在填充数组之前调用ensureCapacity方法:
staff.ensureCapacity(100);
另外,还可以把初始容量传递给ArrayList构造器
ArrayList<Employee> staff = new ArrayList<Employee>(100);
16.对i象包装器,自动装箱 p187
Integer类对应基本类型int ,这些类就叫包装器
JavaSE 5.0 改进:便于添加或获得数组元素
list.add(3);
自动转换为
list.add(Integer.valueOf(3));
这种变换称作自动装箱。
自动拆箱(Integer->int)
int n = list.get(i);
翻译为 int n = list.get(i).inValue();
17.参数数量可变的方法 p189
用户可以定义可变参数的方法,并将参数指定为任意类型,甚至是基本类型。
简单示例:其功能为计算若干个数值的最大值
public static double max(double... values)
{
double largest = Double.MIN_VALUE;
for(double v: values)
if(v > largest)
largest = v;
return largest;
}
然后可以这样调用方法
double m = max(3.1, 40,4, -5);