但是如果在方法中改变对象的字段值会改变原对象该字段值,因为改变的是同一个地址指向的内容。
class PassByValueExample {
public static void main(String[] args) {
Dog dog = new Dog("A");
func(dog);
System.out.println(dog.getName()); // B
}
private static void func(Dog dog) {
dog.setName("B");
}
}
[StackOverflow: Is Java “pass-by-reference” or “pass-by-value”?](https://gitee.com/vip204888/java-p7)
float 与 double
--------------
1.1 字面量属于 double 类型,不能直接将 1.1 直接赋值给 float 变量,因为这是向下转型。Java 不能隐式执行向下转型,因为这会使得精度降低。
// float f = 1.1;
1.1f 字面量才是 float 类型。
float f = 1.1f;
隐式类型转换
------
因为字面量 1 是 int 类型,它比 short 类型精度要高,因此不能隐式地将 int 类型下转型为 short 类型。
short s1 = 1;
// s1 = s1 + 1;
但是使用 += 运算符可以执行隐式类型转换。
s1 += 1;
上面的语句相当于将 s1 + 1 的计算结果进行了向下转型:
s1 = (short) (s1 + 1);
[StackOverflow : Why don't Java's +=, -=, \*=, /= compound assignment operators require casting?](https://gitee.com/vip204888/java-p7)
switch
------
从 Java 7 开始,可以在 switch 条件判断语句中使用 String 对象。
String s = “a”;
switch (s) {
case "a":
System.out.println("aaa");
break;
case "b":
System.out.println("bbb");
break;
}
switch 不支持 long,是因为 switch 的设计初衷是对那些只有少数的几个值进行等值判断,如果值过于复杂,那么还是用 if 比较合适。
// long x = 111;
// switch (x) { // Incompatible types. Found: ‘long’, required: ‘char, byte, short, int, Character, Byte, Short, Integer, String, or an enum’
// case 111:
// System.out.println(111);
// break;
// case 222:
// System.out.println(222);
// break;
// }
[StackOverflow : Why can't your switch statement data type be long, Java?](https://gitee.com/vip204888/java-p7)
四、继承
====
访问权限
----
Java 中有三个访问权限修饰符:private、protected 以及 public,如果不加访问修饰符,表示包级可见。
可以对类或类中的成员(字段以及方法)加上访问修饰符。
* 类可见表示其它类可以用这个类创建实例对象。
* 成员可见表示其它类可以用这个类的实例对象访问到该成员;
protected 用于修饰成员,表示在继承体系中成员对于子类可见,但是这个访问修饰符对于类没有意义。
设计良好的模块会隐藏所有的实现细节,把它的 API 与它的实现清晰地隔离开来。模块之间只通过它们的 API 进行通信,一个模块不需要知道其他模块的内部工作情况,这个概念被称为信息隐藏或封装。因此访问权限应当尽可能地使每个类或者成员不被外界访问。
如果子类的方法重写了父类的方法,那么子类中该方法的访问级别不允许低于父类的访问级别。这是为了确保可以使用父类实例的地方都可以使用子类实例,也就是确保满足里氏替换原则。
字段决不能是公有的,因为这么做的话就失去了对这个字段修改行为的控制,客户端可以对其随意修改。例如下面的例子中,AccessExample 拥有 id 共有字段,如果在某个时刻,我们想要使用 int 去存储 id 字段,那么就需要去修改所有的客户端代码。
public class AccessExample {
public String id;
}
可以使用公有的 getter 和 setter 方法来替换公有字段,这样的话就可以控制对字段的修改行为。
public class AccessExample {
private int id;
public String getId() {
return id + "";
}
public void setId(String id) {
this.id = Integer.valueOf(id);
}
}
但是也有例外,如果是包级私有的类或者私有的嵌套类,那么直接暴露成员不会有特别大的影响。
public class AccessWithInnerClassExample {
private class InnerClass {
int x;
}
private InnerClass innerClass;
public AccessWithInnerClassExample() {
innerClass = new InnerClass();
}
public int getValue() {
return innerClass.x; // 直接访问
}
}
抽象类与接口
------
**1\. 抽象类**
抽象类和抽象方法都使用 abstract 关键字进行声明。抽象类一般会包含抽象方法,抽象方法一定位于抽象类中。
抽象类和普通类最大的区别是,抽象类不能被实例化,需要继承抽象类才能实例化其子类。
public abstract class AbstractClassExample {
protected