2012/12/28(第4章 类)
1 用var声明局部变量
p109
在java10中可以利用var 来声明变量类型 ide会自动推导类型 (类似c++中的auto类型)
例如
Employee harry = new Employee("Harry Hacker");
利用var
var harry = new Employee("Harry Hacker");
2 null值的应用
p109
对一个被复制为null的变量调用方法会引起NullPointException异常
LocalDate birthday = null;
String s = birthday.toString();
这个错误类似数组越界,是很严重的错误,对于这个错误有两种解决方法,“宽容型”和“严格型”
2.1 宽容型:
发现变量是null值时,使其变成一个其他的值,在java9中提供了一个方法
public Employee(String n, double s, int year, int month, int day)
{
name = Objects.requireNonNullElse(n,"unknow");//如果name值为null,则改为unknown
...
}
2.2 严格型:
发现变量是null值时,直接报错,在java9中提供了一个方法
public Employee(String n, double s, int year, int month, int day)
{
Objects.requireNonNull(n,"name can't be null");
name = n;
...
}
这个方法看起来没啥用,因为还是会出NullPointException的报错,但是这个报错会提供这个问题的描述和问题所处位置
3 隐式参数和显式参数
p110
举例对于一个对象的方法调用
employee007.raiseSalary(5);
前面的对象emploee007就是隐式参数(也称为方法的调用者),后面括号中的数值就是现式参数
4 封装的优点
p111
1,封装实现了getter和setter方法,防止类内的变量被随意修改,同时也可以设置getter和setter的权限等级来实现分级访问或者修改
2,同时,对于封装好的方法,如果在类内的某些参数发生了改变,我们只需要调整getter或setter函数便可保证整个代码继续可用,而不需要去找到每个可能使得代码异常的地方,如下
class Employee
{
private string name;
public string getName()
{
return name;
}
}
如果将name改成firstname和lastname的组合,也只需要更改getter方法,外界对方法怎么实现并不在意
class Employee
{
private string firstName;
private string lastName;
public string getName()
{
return firstName + " " + lastName;
}
}
3,同时,getter和setter也可用于错误检查,例如setSalary可检查在设置薪资时是否为小于0的异常值
public void setSalary(int s)
{
if(s <= 0)
{
system.out.println("Setting of salary in fault!");
return;
}
salary = s;
}
警告 不要写返回可变对象引用的getter(返回 可变对象引用 的getter) 如下
class Employee
{
private Date hireDay;
...
public Date getHireDay()
{
return hireDay;
}
...
}
public static void main(string[] arg)
{
Employee harry = ...;
Date d = harry.getHireDay();
double tenYearInMilliSeconds = 10*365.25*24*60*60*1000;
d.setTime(d.getTime() - (long) tenYearsInMilliseconds);
//let's get Harry ten years of added seniority
}
在上面的代码中并没有写Employee中hireday的setter,但是由于返回了类内的hireday的引用,可以声明一个Date d来接受这个引用,再利用Date中的setter更改这个引用指向的值,这就破坏了封装的意义也破坏了hireday的private权限
如果需要返回可变对象引用,应当使用克隆后的副本返回,防止上述问题发生
class Employee
{
private Date hireDay;
...
public Date getHireDay()
{
return (Date) hireDay.clone();
}
...
}