Java基础回顾(一)

考试结束去投简历自卑了(惨)。好久没碰编程了,很多概念也都模糊了。为了保护一下可怜的自尊心,整理一下Java比较基础的内容。之后可能会考虑把JVM的相关内容整上来。

参考为 中国大学MOOC 华东师范大学 的三门Java课程。

类和对象:

1) Java的方法参数传递只有值传递一种。

基本类型,将原有的数据拷贝一份,方法内的操作对原有的数据不会有影响。

对象类型,将对象作为参数传递的时候实际上是将对象的地址传递进去。

public void tricky(Point arg1, Point arg2) {
    arg1.x = 100;
    arg1.y = 100;
    Point temp = arg1;
    arg1 = arg2;
    arg2 = temp;

    System.out.println("Inside func arg1 x: " + arg1.x + ", y: " + arg1.y);
    System.out.println("Inside func arg2 x: " + arg2.x + ", y: " + arg2.y);
}
public static void main(String[] args) {
    Point p1 = new Point(2, 3);
    Point p2 = new Point(2, 3);
    System.out.println("p1 x: " + p1.x + ", y: " + p1.y);
    System.out.println("p2 x: " + p2.x + ", y: " + p2.y);

    tricky(p1, p2);

    System.out.println("p1 x: " + p1.x + ", y: " + p1.y);
    System.out.println("p2 x: " + p2.x + ", y: " + p2.y);
}
===========================================================================
p1 x: 2, y: 3
p2 x: 2, y: 3
Inside func arg1 x: 2, y: 3
Inside func arg2 x: 100, y: 100
p1 x: 100, y: 100
p2 x: 2, y: 3

2)类的成员变量默认有值。局部变量没有初始化没有默认值。

3)每一个Java类一定有构造函数。如无显示定义,编译器会自动产生空的无形参构造函数。

4)每个子类的构造函数,第一句话都默认调用父类的无参数构造函数super()

5)类的属性最好为私有,方法为公有。

6)一、this指向本类中的成员变量。二、this指向本类中的成员方法。三、this可以当做构造函数使用。

7)子类继承父类所有属性和方法。(private不能直接访问,但可以通过调用父类的方法来访问父类的私有成员属性)

8)同方法名同参数的情况下,本类的方法优先级比父类高。

9)Java的类只能继承一个类,无继承的类默认继承Object类。构建出由java.lang.Object的类型继承树。

10)类暂时有方法未实现,需要被定义为abstract抽象类。抽象类不可new。子类继承抽象类时,必须实现父类所有abstract方法,如果不能完全实现,子类也必须被定义为抽象类。

11)一个类所有的方法都未实现,可以将其列为接口interface(特殊的类)。类只能继承extends一个类,但可以实现implements多个类。继承和实现可以同时。

12)接口可以继承多个接口。没有实现的方法会叠加。类实现接口,就必须实现所有未实现的方法,如未实现,则只能定义为抽象类。

13)类型可以相互转型,但只限制于有继承关系的类。子类可以转化为父类,而父类不可以转化为子类。

14)多态:以统一的接口来操纵某一类中不同的对象的动态行为(接口内容由其子类自己实现。对接口进行统一的操作,子类自己定义的内容可以各不相同。)。对象之间的解耦(利用转型和多态,不影响真正方法的调用,成功地将调用类和被调用类解耦)。

15)static变量只依赖于类存在(通过类即可访问,无论实例多少,指向的内存都一样。所有实例都共享一个静态变量),不依赖于对象实例。(未建立实例可以直接调用类中的静态变量)

16)static方法也无需通过对象来引用,可以通过类名直接引用。静态方法中只能使用静态变量。非静态方法可以调用静态方法,而静态方法不能调用非静态方法。

17)代码块:static块只在类第一次被加载时调用,匿名块每次new出都执行。调用顺序为 static块>匿名块>构造函数。

18)单例模式:一个类在整个程序运行过程中,只存在一个实例在内存空间。(1.用static共享对象实例,2.用private构造函数,防止外界new操作)

19)Final:1.Final类不可再被继承。2.子类不可重写父类的Final方法。3.Final的变量不能再次赋值(基本类别变量)。4.Final一个对象实例(对象变量),不能修改其指针,只能修改指针指向的值。

20)常量设计:不会修改的变量。public(方便访问) final(只读) static(只要一份)。接口内定义的变量默认都是常量。

21) 常量池:基本类型的包装类/字符串都建立了常量池。常量池中相同的值只储存一次,节省内存,共享访问。

基本类型包装类 (Boolean / Byte / Short / Integer / Long / Character / Float / Double)

Boolean:true/false

Byte:-128~127 , Character:0~127 , Short/Int/Long:-128~127

Float/Double:没有缓存(常量池)

22)不同创建方式导致对象存放的位置不同。

常量式赋值创建,放在栈内存。(会被常量化){Integer a = 10;}

new对象进行创建,放在堆内存。(不会常量化){Integer a = new Integer(10);}

int i1 = 10;
Integer i2 = 10;
Integer i3 = new Integer(10);
System.out.println(i1 == i2);//true  基本类和包装类比较,自动拆箱比较
System.out.println(i1 == i3);//true  同上
System.out.println(i2 == i3);//false  两个对象比较,比较其地址是否相同,而创建方式不同导致存放地址不同。
Integer i4 = new Integer(5);
Integer i5 = new Integer(5);
System.out.println(i1 == (i4+i5));//true
System.out.println(i2 == (i4+i5));//true
System.out.println(i3 == (i4+i5));//true  (i4+i5)操作自动拆箱,结果为一个int 10
Integer i6 = i4+i5;
System.out.println(i1 == i6);//true
System.out.println(i2 == i6);//true
System.out.println(i3 == i6);//false  Integer i6 = i4+i5等同于Integer i6 = 10

涉及变量和new,编译器不会自动优化常量池。