仅供参考。
阅读Java核心技术Ⅰ
第一章 Java程序设计概述
关键术语
简单性
Java语法是C++的语法的一个纯净的版本。
面向对象
与C++旗鼓相当,简单的说面向对象是一种程序设计技术
分布式
Java应用程序能够通过URL打开和访问网络上的对象,其便捷程度就好像访问本地文件一样。
健壮性
Java的设计目标之一在于使得Java编写的程序具有多方面的可靠性。Java和C++最大的不同在于Java采用的指针模型可以消除重写内存和损坏数据的可能性,Java编译器可以检测许多其他语言再运行时才能检测出来的错误。
安全性
防范各种攻击:
- 运行时堆栈溢出。如蠕虫和病毒常用的攻击手段
- 破坏自己的进程空间之外的内存
- 未经授权读写文件
后来Java第一版开发包发布了之后搞得很难受,遭遇了很多次的高调攻击。Java浏览器产检不再信任远程代码,除非代码有数字签名而且用户同意执行这个代码。
体系结构中立
简单来说就是语言无关性,无论哪种语言按照虚拟机规范生成.calss字节码文件,都可以再JVM上快乐的奔跑。
可移植性
一次编译到处运行,在Java中,数据类型具有固定的大小,这消除了代码移植时令人头痛的问题。Java中的int永远为32位的整数。
解释性
Java解释器可以在任何移植了解释器的机器上执行Java字节码文件。
高性能
尽管对解释后的字节码性能以及比较满意,但是在有些场合下还需要更加高效的性能。字节码可以(在运行时刻)动态的翻译成对应运行这个应用的特定的CPU的机器码。
多线程
Java是第一个支持并发程序设计的主流语言。带来更好的交互响应和实时行为。
动态性
它能够适应不断发展的环境。库中可以自由地添加新方法和实例变量,而对客户端没有任何的影响。在Java中找出运行时类型信息十分简单。
Java applet与Internet
在网页中运行的Java程序称为applet。在网页中插入一个applet就如同在网页中嵌入一个图片,可以与用户进行交互。
关于Java的常见误解
- Java时HTML的扩展
- 使用XML,所以不需要Java
- Java是一种非常容易学习的语言
- Java将成为适用于所有平台的通用性语言
- Java只不过是另外一种程序设计语言
- Java是专用的、应该避免使用
- Java是解释型的,因此对于关键的应用程序速度太慢了
- 所有的Java程序都是在网页中运行的
- Java程序主要的是安全风险
- JavaScript是Java的简易版
- 使用Java可以使用廉价的Internet设备取代桌面计算机
第二章 JAVA程序设计环境
1.2-1.4版本的JDK叫做SDK
JRE是运行时环境,包含虚拟机不包含编译器,开发人员不用这个,专门为不需要编译器的用户而提供的。
JavaSE是Java的标准版
JavaEE开发web
JavaME贴近于Android开发(我不知道,我猜的)
常用的继承环境开发:
eclipse
InelliJ IDEA(推荐,好用不过要破解)
第三章 Java的基本程序设计结构
前面略了,一看就会。
数据类型
Java是一种强类型语言,这就意味着必须为每一个变量声明一种类型。JS就不是。四种整形、两种浮点、一种用于表示Unicode编码的字符单元的字符类型char和一种表示真值的boolean类型。
整形
类型 | 存储需求 |
---|---|
int | 4字节 |
short | 2字节 |
long | 8字节 |
byte | 1字节 |
int类型最常用,长整型数值有一个后缀L或l。十六进制前缀为0x,八进制前缀为0。
从Java7开始,前缀0b或者0B表示二进制数,还可以为数字字面量加下划线,如1_000_000表示一百万。
int number=1_000_000;
浮点类型
类型 | 存储需求 |
---|---|
float | 4字节 |
double | 8字节 |
float的有效位数为6-7位,double的有效位数为15位。
绝大部分情况下都采用double,很多情况下float类型的精度很难满足需求。实际上只有很少的情况适合使用float类型,例如需要单精度数据的库,或者需要存储大量的数据。
可以使用16进制表述浮点数,使用p表示指数而不是e。
溢出或者出错情况表示浮点数的三个数值:
- 正无穷大 Double.POSITIVE_INFINITY
- 负无穷大 Double.NEGATIVE_INFINITY
- NaN(不是一个数字)Double.NaN
正整数除以0的结果位正无穷大。计算0/0或者负数的平方根结果为NaN。
System.out.println(1.0/0);//Infinity
System.out.println(-1.0/0);//-Infinity
检测一个数是不是NaN使用Double.isNaN()方法。
注意:浮点数值不适用于无法接受舍入误差的金融运算当中。
System.out.println(2.0-1.1);//0.8999999999999999
如果在计算中不允许有任何舍入误差,就应该使用BigDecimal类。
char类型
单个字符,有些Unicode字符可以用一个char表示,另外一些Unicode字符则需要两个char值。char类型的字面量要用单引号括起来。占俩字节,也可以用表示为十六进制,范围从\u0000到\uffff。
Unicode转义序列会在解析代码前处理,例如\u0022表示"。
System.out.println("\u0022+\u0022");//空 等效于 ""+""
更隐秘的,注释也要当心\u。
//Look inside c:\users
会报错Error:(13, 27) java: illegal unicode escape
因为\u后面没有跟着四个十六进制的数
Unicode和Char类型
了解Unicode编码机制。
每个国家都有自己的编码标准:中国的GB 18030和BIG-5、美国的ASCII、西欧国家的ISO 8859-1。就会产生俩问题,一个是对于任意给定的代码值,在不同的编码方案下对应不同的字母;一个是采用大字符集的语言其编码长度有可能不同。例如,有些常用的字符采用单字节编码,而另一些需要两个或者更多的字节。
Unicode就是为了解决这些问题,一开始设计者本来觉得两个字节的代码宽度足以应对世界上各种语言的所有字符进行编码,并由足够的空间留给未来进行扩展,后来不可避免的事情发生了,Unicode字符超过了65536个,主要原因是因为增加了大量的汉语、日语和韩文。现在16为的char类型已经不能满足描述所有Unicode字符的需要了。
Java如何解决的呢?
码点:指与一个编码表中的某个字符对应的代码值。在Unicode中码点采用十六进制书写,并加上U+前缀。Unicode的码点分为17个代码级别。第一级别成为基本的多语言级别,码点从U+0000到U+FFFF,其中包括经典的Unicode码,其余的16个级别从U+10000到U+10FFFF(多的鸭批),其中包括一些辅助字符。
UTF-16编码采用不同长度的编码表示所有的码点。每个字符用16位表示,通常被称为代码单元。而辅助字符采用连续的代码单元进行编码。这样的编码落入多语言级别中空闲的2048字节内,通常被称为替代区域,[U+D800-U+DBFF用于表示第一个代码单元,U+DC00-U+DFFF用于第二个代码单元](说实话这里我吐了,有点懵逼)。
在Java中,char类型描述了UTF-16编码中的一个代码单元。
强烈建议不要在程序中使用char类型,除非确实需要。最好将字符串作为抽象数据类型处理。
boolean类型
简单false和true。
变量
天天说,变量名是由字母数字下划线组成,大小写敏感。
变量名长度基本没有限制,但是JVM中还是有限制,最大为64KB,相信没有哪个大佬能写到64KB。
如果想要知道哪些Unicode字符属于Java中的"字母",可以使用Character类的isJavaIdentifierStart和isJavaIdentifierPart方法来检查。
System.out.println(Character.isJavaIdentifierPart('a')); //true
System.out.println(Character.isJavaIdentifierStart('a'));//true
不要用Java保留字做变量名,众所周知。
变量初始化
Java中不要使用未初始化的变量,不然会报错。
不过编译。
常量
final关键字修饰的叫做常量。表示这个变量只能赋值一次,一旦赋值后就不能再修改了。习惯上常量名使用全大写。
Java中通常希望某个常量可以在一个类中的多个方法使用,将这个常量成为类常量。使用static final设置一个类常量。再将这个常量声明为public,那在其他类中与可以使用。
运算符
/ + - * 这些
整数被除以0会产生一个异常,浮点数除以0NaN。
很多Intel 处理器计算x*y,并且将结果存储在80位的寄存器中,再除以z并将结果截断为64位。这样可以得到一个更加精确的计算结果,并且还能够避免产生指数溢出。但是,这个结果可能与始终在64位机器上计算的结果不一样。因此,Java 虚椒机的最初规范规定所有的中间计算都必须进行截断。这种行为遭到了数值计算团体的反对。截断计算不仅可能导致溢出,而且由于截断操作需要消耗时间,所以在计算速度上实际上要比精确计算慢。为此,Java程序设计语言承认了最优性能与理想结果之间存在的冲定,并给予了改进。在默认情况下,虚拟机设计者允许对中间计算结果采用扩展的精度。
默认情况下,虚拟机设计者允许对中间计算结果采用扩展的精度。但是使用strictfp关键字标记的方法必须使用严格的浮点计算来生成可再生的结果。
例如,可以把main方法标记为:
public strictfp static void main(String[] args)
所有指令都将使用严格的浮点计算。
数学函数与常量
Java中的Math类。
提一个floorMod方法,整数取余数的问题。
负整数取余为一个负数,有时候这个结果处理起来比较麻烦。例如关于调钟表的要这么写:
((position+adjustent)%12+12)%12。麻烦
使用floorMod替代floorMod(position+adjustent,12)总会得到一个0-11的数。
Π常量、e常量
Math.PI;
Math.E;
对于浮点数运算,如果想要得到一个可预测的结果比运算输速度更重要的话就使用StrictMath类。
数值类型之间的转换
两个不同类型的数值之间进行运算。
- 一个为double转为double
- 一个为float转为float
- 一个为long转为long
- 否则转为int
强制类型转换
合理的转换,用(type),例如
int a=10;
double c=(double)a;
小数→整数 四舍五入Math.round()
关于String的转换使用
String.valueOf()
结合赋值运算符
x+=3.5 会把结果转为x类型。
int a=10;
a+=3.5;
System.out.println(a);//输出13
+=是右结合运算符
a+=b+=c等价于
a+=(b+=c)
字符串
- 获取字串使用substring方法
- 拼接使用+,把多个字符串使用一个定界符分分割使用join(定界符,字符串1,字符串2…)
- 多个字符串拼接不要使用+,字符串经常变不要使用String类。
- 检查字符串是否相等使用equals方法,不要使用==,这个会比较地址。
- 空串长度是0,null表示对象为空。判断一个串长度不为0且为空对象要写成str!=null&&str.length()!=0,注意先后顺序。反了的话对象为null时调用length方法会出现错误。
构建字符串
每次使用+连接字符串,都会产生一个新的String对象,即耗时间又耗费空间,是哟StringBuilder类就可以避免这个问题的发生。
拼接串使用append方法。
关于StringBuffer和StringBuilder:
StringBuilder的前身时StringBuffer。
StringBuilder单线程,效率较高
StringBuffer多线程编辑,效率比较低。
单线程编辑字符串使用StringBuilder。
输出与输出
读取输入
Scanner scanner=new Scanner(System.in);
scanner.next(); //空格结束
scanner.nextLine();//回车结束
scanner.nextInt();//输入一个整形数字
scanner.nextFloat();//单精度浮点型
scanner.nextDouble();//双精度浮点型
格式化输出
沿用了c语言的printf
使用System.out.print()进行格式化输出。
可以使用String.format方法创建一个格式化的字符串,而不打印输出。
String name="zjx";
int age=22;
String introduce=String.format("hello,my name is %s,and age is %d",name,age);
System.out.println(introduce);//hello,my name is zjx,and age is 22
输出日期和格式转换
System.out.printf("%1$s %2$tB %2$td,%2$tY","date:",new Date());
//date: July 18,2020
文件输入与输出
想要对文件进行读取,就需要使用File对象构造一个Scanner对象
Scanner in=new Scanner(Paths.get("myFile.txt","UTF-8"));
设置字符编码(这里是UTF-8)是个好习惯。
想要写入文件就要构造一个PrintWriter,只需要提供文件名。
PrintWriter out=new PrintWriter("myFile.txt","UTF-8");
创建直接就使用print、println等应用。
JAVASE中的绝对路径和相对路径。
相对路径:是从工程名开始算起的。
绝对路径:盘符:/目录/文件名
控制流程
- 块作用域,静态块
- 条件语句 if else
- 循环 while
- 确定循环 for
- 多重选择 switch
- 中断控制流程 break goto,多重循环控制嵌套,可以给每一层循环加一个标签,可以使用 break 标签;跳出这个循环。continue跳出单层循环
run_for:
for (int i=0;i<100;i++){
if (i==100){
break run_for;
}
}
大数值
BigInteget 对整型大数值进行运算
BigDecimal对浮点型大数值进行运算