其实写这些东西挺累的,看的时候觉得很容易理解,写起来要将思想转换为文字有点小难受
3.1 一个简单的Java应用程序
定义了几个定理,具体如下:
- 如果当前源代码需要作为起始函数,那么需要保证其中的存在一个与当前源代码文件名相同的公有类(比如FirstSample.java和public class FisrtSample定义),同时也需要保证其中存在一个main函数,并且该main函数需要为静态成员函数。
- main函数最好一直表示为public static void main(String args[])的形式,这从C++的角度来讲就是保证类中有一个可以外部调用的静态成员函数罢了,也就相当于将传统的int main函数换成了这个;而从Java的角度来讲就是main函数必须要拥有一个外壳类,这种方法的好处相对于C++中的int main而言我个人感觉是非常方便做任意类的单元测试工作。
- 大括号{}的摆放根据喜好而定,作者与本人均为对齐党,所以本人表示很开心。
3.2 注释
与C++基本相同。
- /* 我是注释 */ :没啥好说的;
- //我是注释:也没啥好说的;
- /** 我是注释 */:Java特有注释,用于设计javadoc,我个人认为这个功能很棒;
3.3 数据类型
通过JVM,所有的数据类型所占字节数在任意机器上均保持恒定。
3.3.1 整型
长数据类型加后缀(4000L),十六进制加前缀(0xCA、0XCA),八进制加前缀(010,容易混淆不建议使用),二进制加前缀(0b1001、0B1001)。
Java7新特性:数字中间加下划线不改变原意(1_000_000以及0b1111_0001)。
类型 | 大小 | 类型 |
---|---|---|
int | 4字节 | 2-32 ~ 232-1 |
short | 2字节 | 2-16 ~ 216-1 |
long | 8字节 | 2-64 ~ 264-1 |
byte | 4字节 | 2-8 ~ 28-1 |
3.3.2 浮点类型
float类型加后缀(3.14F、3.14f),double类型可以加后缀(3.14D、3.14d),不过如果不加后缀往往默认为double类型。
Double.POSITIVE_INFINITY表示正无穷大的浮点数,Double.NEGATIVE_INFINITY表示负无穷大的浮点数,Double.NaN表示不存在的浮点数。
类型 | 大小 | 类型 |
---|---|---|
float | 4字节 | 大约 ±3.402 823 47E+38F(有效位数为6- 7位) |
double | 8字节 | 大约 ±1.797 693 134 862 315 70E+308(有效位数为15位) |
3.3.3 char类型
这个类型与C++的char类型比较近似,表示单个字符,不过同时也可以使其该类型对Unicode字符进行描述,其中存在一些特殊字符的转义序列。
(这里说明下,MAC OS 系统行末结束符为\r,UNIX 系统行末结束符为\n,window 系统行末结束符为\n\r)
转义序列 | 名称 | Unicode值 |
---|---|---|
\b | 退格(backspace) | \u0008 |
\t | 制表(tab) | \u0009 |
\n | 换行(光标下移一行) | \u000a |
\r | 回车(光标移至行首) | \u000d |
\" | 双引号 | \u0009 |
\’ | 单引号 | \u0027 |
\\ | 反斜杠 | \u005c |
3.3.4 Unicode与char类型
这里书里解释了两者之间的关系,简单来说就是Java选用的是最初的16位Unicode字符集,但是计划赶不上变化,后来Unicode字符超过了16位大小,所以Java采用了一种自己的方式来解决该问题,具体如下。
- 码点(code point),是指与一个编码表中的某个字符对应的代码值,其为十六进制且必须加上前缀,比如U+0041。在Unicode中的码点分为17个代码级别,第1个代码级别为基本的多语言级别(basic multilingual plane),其码点表示范围为U+0000到U+FFFF(范围内有2048个位置作为替代区域编码存在),其中包括经典的Unicode代码;其余的16个代码级别从U+10000到U+10FFFF,其中包括一些辅助字符。
- 代码单元(code unit),是指一个16位长度的编码,在Java中通过char类型描述UTF-16中的一个代码单元。在基本的多语言级别(即第1个代码级别)中往往只是用1个代码单元来编码,而对于其他辅助字符(即另外的16个代码级别)则采用2个代码单元进行编码。辅助字符使用了基本的多语言级别中的2048个空闲(非法)位置进行表示,这2048个位置被称为替代区域(surrogate area),其中U+D800至U+DBFF共1204个码点值用于辅助字符中的第1个代码单元,也被称为高位替代区域;其中U+DC00至U+DFFF共1204个码点值用于辅助字符的第2个代码单元,也被称为低位替代区域。
- 判断方式:根据高低位替代区域中各1024个码点值,其能组成10242(1048576)个辅助字符,加上基本的多语言级别中的216-2048(63488)个字符,共计1112064个字符,这即为Java中所能表示的最多字符数。在判断当前字符为基本的多语言级别或为辅助字符时,只需判断当前char类型中(即当前代码单元)的编码值为高位替代区域或非高位替代区域:如为高位替代区域则查看下一位char类型(即下一个代码单元)中是否为低位替代区域,是则代表当前通过两个代码单元表示了一个辅助字符,否则当前字符的编码存在问题;如不为高位替代区域则代表当前通过一个代码单元表示了一个基本的多语言级别字符。
3.3.5 boolean类型
Java中的boolean值是纯粹的bool值,只有true和false不能像C++一样自由转换为整型的0和1。
3.4 变量
区分大小写。
3.4.1 变量初始化
Java没有像C++一样严格的“声明”与“定义”的区分,而是分为变量的“声明”与“初始化”,换句话说,Java希望声明时最好带有初始化。
3.4.2 常量
Java使用final表示常量,对于变量的定义上其与const是一回事。
3.5 运算符
常规
3.5.1 数学函数与常量
大多数据函数都在Math包中,调用其中的方法使用Math.xxx(比如Math.cos)这样的操作,个人理解这都是Math这个类中的静态成员函数,类似于在C++中的Math::cos这样的调用。
3.5.2 数值类型之间的转换
总结来说,整型之间,小可转大且精度不损失;浮点型之间,小可转大且精度不损失;char转int精度不损失,int转float精度损失,int转double精度不损失,long转float精度损失,long转double精度损失。
3.5.3 类型强转
C式转换方式(int)这样,但是不要对boolean类型强转。
3.5.4 - 3.5.9 常规操作
3.6 字符串
Stirng类
3.6.1 子串
substring(int startPlace, int length)方法截取
3.6.2 拼接
“+”号实现拼接,join(String seprator, String a, String b,…,String n),通过分隔符进行字符串拼接
3.6.3 不可变字符串
Java的字符串类似于C++中的char*指针型字符串,这代表了无法直接修改String字符串中的字符,其关键特点在于实现了对字符串的共享,即无论是子串还是拼接都是使用的原始字符串的内存。
3.6.4 字符串相等判断
boolean equals(String string)方法判断相等,int compare(String string)也可以。
3.6.5 空串与Null串
Java中的NULL注意要写成null。
3.6.6 码点与代码单元
int length()方法返回的是代码单元的数量,char charAt(int place)方法返回的是place位置的代码单元。
int codePointCount(int startPlace, int endPlace)返回的是码点的数量,int offsetByCodePoints(int startPlace, int codeNumber)返回的是字符串中第codeNumber个码点的位置索引,int codePoint(int index)返回的是第index个位置索引的码点值。
遍历字符串时考虑到码点与代码单元的不同性,普通操作起来比较麻烦,所以可以使用String类中的codePoints方法生成一个所有码点int值的流来进行遍历。
3.6.7 - 3.6.8 阅读文档即可
3.6.9 构建字符串
StringBuilder类,实现了诸如append、insert、setCharAt与delete等操作以便于字符串构建,当构建完成时通过toString操作即可得到String类。
3.7 输入输出
标准输入流System.in,标准输出流System.out
3.7.1 读取输入
其中读取标准输入流的操作(借助util包中Scanner类实现):
Scanner in = new Scanner(System.in);
System.out.println("Enter your name:");
String name = in.nextLine();
System.out.println("Enter your age:");
int age = in.nextInt();
in.close();
3.7.2 格式化输出
沿用了C语言的printf库,其中单个(%X)的方式沿用,使用(%tX)用于表示日期相关类Date的时间。
3.7.3 文件输入和输出
在学流之前可能还是不太了解,只能先按书本上的Scanner与PrintWriter方式先写一下:
PrintWriter out = new PrintWriter("MyFile.txt"); //PrintWriter 文件输出流(现在的写法每次都会重写),类比于输出流ostream(还有System.out系统输出)
out.println("we can 1");
out.close();
Scanner in = new Scanner(Paths.get("MyFile.txt")); //Scanner 读取文件和其他都可以,换句话说Scanner就是输入流,所有的东西都可以变成该输入流istream
System.out.println(in.nextLine());
in.close();
这里附带一下相关的流的选用表。
3.8 控制流程
基本与C++/C相同。
3.8.1 块作用域
值得一提的是,Java不允许局部变量的定义与全局变量的名字相同,即不允许发生嵌套。
3.8.2 - 3.8.5 相同流程
3.8.6 中断控制流程语句
使用带标签的break语句来取代goto语句,在使用时需要保证标签必须放在希望跳出的最外层循环之前,比如:
back;
while(...)
{
for(...)
{
...
if(...)
break back;
...
}
}
3.9 大数值
BigInteger与BigDecimal两个类,两者均实现了类中的加减乘除余操作,同时均通过类中的valueOf静态方法将普通的数值转变为大数值。
3.10 数组
Java的数组同样为静态大小数组,在定义时int a[]与int[] a均可。
3.10.1 for each循环
这里与C++ 11中的for auto循环神似,只是没有了引用符号。
3.10.2 数组初始化
两种初始化方式,均在堆上创建数组。
int a[] = new int[100]; //动态初始化创建一个数组a,new的方式,a实际上就是个指针数组,指针在栈中,指针所指的数据在堆中
int b[] = {2,3,4}; //简化的静态初始化创建了一个数组b,实际与a情况一样,区别在于动态初始化分配数组大小系统设置初始值,静态初始化分配元素系统根据元素数量设置大小
// int b[] = new int[] {2,3,4}; //这里是非简化的静态初始化
3.10.3 数组拷贝
直接复制拷贝是值传递(Java只有值传递),所以传的是数组首位置的指针,为浅拷贝;使用Arrays类中的静态方法copyOf为深拷贝,重新申请的内存空间。
3.10.4 命令行参数
String[]表示字符数组,在Eclipse中的程序自变量输入,如下:
3.10.5 数组排序
Array类中的静态方法sort即可。
3.10.6 多维数组
int [][] temp;根据这个声明方式我就看出了这个比C++的那个好用。
3.10.7 不规则数组
说穿了就是先定义一个有行的二维数组:int[][] temp = new int[xxx][];然后再循环所有的行定义其中的列即可,用C++的方式理解还是指针数组的基本道理,到这里写起来明显看着都舒服多了。