目录
一、语句角度
语句执行的顺序问题。我们先看下面一道例题
public class B
{
public static B t1 = new B();
public static B t2 = new B();
{
System.out.println("构造块");
}
static
{
System.out.println("静态块");
}
public static void main(String[] args)
{
B t = new B();
}
}
请问以上代码的输出结果是什么?
思考:我们首先要进行类的加载。那么类加载的顺序是什么呢?静态代码块和静态属性按照代码的书写顺序执行。所以先执行public static B t1 = new B()和public static B t2 = new B();这两句,这两句需要调用构造代码块,所以直接输出“构造块”“构造块”。然后再执行静态代码块“静态块”。此时类的加载完成,进入main函数开始new一个B对象,那么对象的构造又是什么顺序呢?构造代码块和属性按照代码书写顺序执行然后再是构造方法。所以输出“构造块”。综上所知,此题的结果为“构造块”“构造块”“静态块”“构造块”。
小结:
①使用类之前,必须进行类的加载(静态代码块和静态属性按照代码的书写顺序执行)
②对象的实例时,必须进行对象的构造过程(构造代码块和属性按照代码书写顺序执行然后再是构造方法)
③子类的加载之前,必须保证父类先加载完成
④子类的对象构造之前,先把父类的对象构造完。
二、数据角度
此处的重点为,数据到底放在内存中的哪里?先看这张图
我们可以将Java中的数据分成以下几个部分。即变量、数组元素、以及对象。其中我们知道对象是放在堆上的,数组元素属于数组对象,那么数组元素也是放在堆上的。那么变量是放在哪里呢?答案是不知道。
变量这个概念太大了,我们需要分情况讨论。其中我们知道局部变量是放在栈区的。跟随类的静态属性存放于方法区。跟随对象的实例属性是存放在堆上的。 补充一点:语句数据(字节码)放置于方法区(无论静态方法还是普通方法)
三、几个重要的关键字
static:1、静态导入
2、修饰静态属性
3、修饰静态方法
4、修饰静态代码块
5、修饰静态内部类
总之static的主要作用是与对象解绑,只和类有关。
final:1、修饰变量(只能赋值一次,不能修改)
2、修饰类(表示不能被继承)
3、修饰方法(表示不能被重写)
abstract:1、修饰类(抽象类)
2、修饰方法发(抽象方法)
四、重载和重写
重载:方法名必须相同,参数类型必须不同,包括但不限于一项,参数数目,参数类型,参数顺序。返回值不做要求
重写:要求两同两小一大原则, 方法名相同,参数类型相同,子类返回类型小于等于父类方法返回类型, 子类抛出异常小于等于父类方法抛出异常, 子类访问权限大于等于父类方法访问权限。[注意:这里的返回类型必须要在有继承关系的前提下比较]
五、抽象类和接口
抽象类是一个设计用来专门被继承的类。抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。在 Java 中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。
抽象方法:如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。
注意:
- 如果一个类包含抽象方法,那么该类必须是抽象类。
- 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。
接口:接口通常以interface来声明。编写接口的方式和类很相似,但是接口并不是类,它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。可以将接口理解为比抽象类更抽象的东西。和抽象类一样。除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
注意:
- 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
- 接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。
- 接口中的方法都是公有的。
和抽象类的区别很多但是主要是
一个类只能继承一个抽象类,而一个类却可以实现(implements)多个接口。
接口之间允许多继承。使用extends
六、异常
Java中异常分为两大类:checkedexception(受查异常)和unchecked exception(未受查异常),未受查异常也可以叫做RuntimeException(运行时异常).他们的主要区别:受查异常在编译时不能被简单地忽略。而运行时异常可以在编译时被忽略。以下代码是之前图书管理系统中的添加书籍代码中的按要求输入价格部分。异常的简单使用方法如下
while(true){
try{
String priceStr = input.prompt("请输入书籍的价格(请输入数字)");
price=Integer.parseInt(priceStr);
break;
}catch (NumberFormatException exc){
System.out.println("请正确输入!!!");
}
}
注意:在try...catch...finally中。finally 关键字用来创建在 try 代码块后面执行的代码块,无论是否发生异常,finally 代码块中的代码总会被执行。
七、Java是值传递还是引用传递
八、总结
总结的总结就是:还需要大量练习和实际操作才能好好掌握