阅读原文:【读】Java核心技术卷1
看到这本书时,我的内心是崩溃的,卷1就700多页,但是这本书是很多前辈所推荐的,想必其中必有精华所在,硬着头皮上吧。
long a = 3.14L 这里注意要用大写的L作为后缀,因为小写 l 有时很像数字 1
注意:当浮点型数字没有后缀时(如:3.14),默认为double类型。另外浮点数值不适用于无法接受舍入误差的金融计算中,如 2.0 - 1.1 结果是 0.89999999999999,为更精确的计算,可以使用BigDecimal类。
正整数除以0的结果正无穷大(如:3/0.0 结果为Infinity),Infinity表示无穷大的概念,0.0并不是真正意义上的0,它只是非常接近0而已。
,0/0或者负数的平方根结果为NaN.(如:0.0/0.0 ,Math.sqrt(-3)结果为 NaN ),对于所有没有良好的数字定义的浮点计算,例如0.0/0.0,或者对负数求平方根其值都是它.
x = x + 4
简写: x += 4
注意: 如果运算符得到一个值,其类型与左侧操作数类型不同,,就会发生强制类型转换,如 int x = 2 ; x += 3.14 ; 这相当于 x = (int)(x + 3.14)
java中借鉴了C和C++的做法,提供了自增自减运算符:n + + 将当前值加1
这种运算符有两种形式:运算符作为前缀和运算符作为后缀。例:
int m = 7 ; int n = 7 ; int a = 2 * ++m; //a=16,m=8 int b = 2 * n++; //b=14,n=8
前缀形式先完成加1,后缀形式会使用原来的值,再加1。
不建议在表达式中使用++,因为这样的代码很容易让人困惑,而且会带来烦人的bug。
&&表示逻辑“与”,||表示逻辑“或”。
这两个运算符是按照“短路”方式来求值的:如果第一个操作数已经能够确定表达式的值,第二个操作数就不会计算了。如:
exp1 && exp2 ,当exp1为flase时,那么exp2就不会执行了。 exp1 || exp2 ,当exp1为true时,那么exp2就不会执行了。
&和| 运算符不采用“短路”方式求值,所以不论第一个操作数是否确定整个表达式的值,两个操作数都会被计算。
一定要用equals()函数,它是判断两个字符串内容是否相等,而 == 是判断两个字符串是否在同一个位置上。如果 == 相等,那么equals一定相等,反之不然。
""是一个Java对象,有自己的串长度(0)和内容(空),当为Null时,表示目前没有任何对象与该变量关联。
检查一个字符串既不是null也不是空串:
if(str != null && str.length() != 0)
要先检查不为null,因为为null时无法调用length()函数。
switch(x){ case x1 : *** break; case x2 : *** break; }
其中x可以为char,byte,short,int类型,到Java SE 7开始,可以是String类型的。
一般不建议使用switch语句,因为break语句的忘记容易导致问题。
学习Java你一定知道下面代码:
public class Massage{ public static void main(String[] args){ System.out.println(args[0]); System.out.println(args[1]); } }
当你在命令行变异运行这个类时:java Massage -hello world
打印结果:
hello world
我们应该尽量减少相互依赖的类存在,如果A类不知道B类,就不会关系B类的变化,这样B类无论怎么变化都不会导致A的bug,软件工程上叫做:让类之间的耦合度最小。
Date是一个用来表示时间点的Date类,LocalDate用来表示大家熟悉的日历表示法。
1.Date和SimpleDateFormatter都不是线程安全的。
2.Date对日期的计算方式繁琐,月份从0开始。
创建一个对象可以通过以下几个方式:
LocalDate local1 = LocalDate.now(); LocalDate local2 = LocalDate.of(2017,10,30);
LocalDate并不包含时间,你可以通过下面获取年月日:
int year = local2.getYear(); int month = local2.getMonthValue(); int day = local2.getDayOfMonth();
当然LocalDate也提供了日期的增减:
local2.pulsDays(100); local2.minusDays(100);
更多方法查看API,这里不做详细表述。
将实例域定义为final,构建对象时必须初始化这个实例域,后面的操作中不能够再对它进行修改。如:
public class Employee{ private final String name; …… }
这个name属性没有setName方法。final修饰符大都应用于基本数据类型或不可变的类或对象。如果类中每个方法都不会改变其对象,那么这个类就是不可变类,如String类。
对于可变的类使用final修饰,会对别人造成混乱。如:
private final StringBuilder sb;
在Employee构造方法中进行初始化
public Employee(){ sb = new StringBuilder(); }
final关键词只是表示存储在sb变量中的对象应用不会再指向其他StringBuilder对象,不过这个对象可以更改:
public void giveGoldStar(){ sb.append( LocalDate.now() + ": Gold star!"); }
public class Employee{ private static int sid = 1001; private int id ; …… }
static 修饰的常量,是面向类的,即无论存在多少Employee对象,sid只存在一个,所有对象将共享一个sid,但id却和对象同存在,多少个对象就有多少个id。(static 修饰后,它属于类,而不属于任何对象)
类似LocalDate.now和LocalDate.of都是使用静态工厂方法来构造对象。
NumberFormat currenyFormatter = NumberFormat.getCurrencyInstance(); NumberFormat percentFormatter = NumberFormat.getPercentInstance(); double x = 0.1; System.out.println(currenyFormatter.format(x)); //输出 $0.10 System.out.println(percentFormatter.format(x)); //输出 10%
为什么不利用构造方法来完成这些操作呢?原因:
方法参数共有两种类型:
double x = 10; harry.raiseSalary(x);
中不论加薪方法具体怎么实现,但x值始终不变。
public void swap(Employee x,Employee y){ Employee temp = x; x = y; y = temp; } Employee a = new Employee("zhang"); Employee b = new Employee("wang"); swap(a,b); //现在x指向wang,y指向zhang System.out.println(a.toString()+"--"+b.toString());
最后你会发现a依然是zhang,b依然是wang,因为形参x,y在执行完后被丢弃了,原来的a,b依然指向之前的的对象。
总结:
当一个类没有提供构造函数时,系统会为这个类提供一个默认的无參构造函数,但当你提供了有参的构造函数时,系统是不会提供无參构造函数的,所以当你要调用无參构造函数时,主动提供无參构造函数或不提供任何构造函数。
类不可变,就可以安全地在多个线程间共享其对象。