~Java入门
Java编程基础知识
这是我个人所写的学习笔记[1],关于Java语法层面的内容已经总结的比较全面。不需阅读其他任何入门书籍,入门就应该简单明了,如果需要提升编程能力,应该要多做编程练习,推荐是自己写Java代码实现自己的需求。如果需要更深入学习Java,就应该多看看那些优秀的书籍,看明白源码。
类和方法
在Java中,一个源程序文件就是一个编译单元,必须有和文件名相同的类名。
Java程序从main方法开始执行。逗号在for循环表示分隔,此外,无其他意义。
类相当于带方法的结构体,Java方法必须在类中定义,方法就是类的成员函数,Java有自动提升的类型转换,Java也有构造函数以初始化类,因此类的引用方式如下:
classname class_var;
类对象的初始化如下(必须):
class_var = new classname(parameter_list);
类的定义格式如下:
1 | |
变量的声明一般在类的首部,方法中也可声明变量,方法也可以有返回值,构造函数必须与类同名,构造函数没有返回值。
在方法中,this代表其所属对象,可以之访问类的成员。
对象引用
一个实例化的类即是实体,即是对象,初始化对象格式如下:
classname class_var = new classname(parameter_list);
方法重载:一个类可以有相同名字的方法,但其参数列表必须不同。使用时根据参数调用不同方法,在找不到方法时,Java通过自动提升类型尝试调用之。构造函数也可以重载。
传递简单类型参数是按值传递,传递对象是引用传递(这相当于C/C++的指针传递)。
方法可以返回对象(包括类),Java也支持递归(方法调用其本身)。
访问指示符:public,private,protected以及默认级。
private修饰,在类中公开,在类以外私有。
默认级,在包中公开,在包以外私有。
static修饰,静态的,声明一个静态量,可以在未创建对象引用之前使用之,并且该类的所有对象共同拥有它。在一个static方法中引用其类的实例变量(方法)都是非法的。有static初始化块,在类中它被提前工作。
可以用点运算符从类的外部调用变量和方法,格式如下:
classname.method() 等等。
final可以用来修饰变量,以防其内容被修改,相当于C/C++的const常量。
数组也是对象,例如:int a[]=new int[10];
一个数组必定包含length成员以表示其长度。
数组构造函数参数不要求固定常量,但必须初始化(或以默认值)。
嵌套类,是在一个类中定义的类,静态的嵌套类不能直接访问上层类(包围类)而必须通过对象引用访问。非静态的嵌套类称为内部类,内部类作用范围仅在内部。嵌套类可以位于方法、类,甚至循环等区域中。
String对象和C/C++中的字符串一样,但其内容是不可变的。StringBuffer对象却是可变的。对String可使用'+'运算符,String等类也可以转为数组。
使用命令行参数,命令行输入:
java classname cmdline_args
这样参数cmdline_args将传给classname的main方法的string数组中。
继承和Object类
继承是面向对象编程技术的一块基石。Java中被继承的类叫超类,继承超类的类叫子类。该子类包含超类所有的变量和方法,并为自己增加了新元素。继承的格式如下:
1 | |
注:Java不支持多超类的继承(这与C++不同),但可以创建一个继承的层次,让子类成为另一子类的超类。然而没有类可以成为自己的超类。子类不可以访问其超类中的private成员。
超类变量可以引用子类对象,如:
superclass_name = subclass_name;
这会将子类中有关超类的部分赋值给超类一个引用。
子类中,在构造函数使用super(...)调用其超类的构造函数。构造函数一般不带修饰词。
子类使用super引用明确超类对象。子类中,成员与其超类成员同名则会隐藏此超类成员。
在多重继承下,构造函数往往先执行超类中的再执行子类的。
子类中有与其超类参数相同的方法,这称为子类的方法重载。
抽象类和接口
抽象类
abstract修饰词,抽象的,通过抽象类,由子类重载某些方法,这些方法(抽象方法)被称为子类的责任引用,因为其并未在超类实现。声明抽象类方法:
abstract type name(parameter_list);
包含抽象方法的类必须声明为抽象类,抽象类只需用abstract修饰class即可。
抽象类不能直接通过new实例化,并且不能定义抽象类的构造函数或抽象的静态方法。所有抽象类的子类必须实现超类中所有的抽象方法,或者它自己是抽象类。
抽象类虽不能实例化但可以引用,因此可以用以指定任何从之派生的对象。
使用final阻止重载,超类的final方法不能被子类覆盖。
使用final阻止继承,在类的声明前加上final即可。
接口
接口,关键字interface,接口与类的语法类似,但不含方法体,缺少实例变量,必须由其他类实现该接口,接口可以认为是"纯抽象的类",格式如下:
1 | |
access可以为public或者为空,接口中的变量都是public static final的常量。接口也可以被继承。
可以定义一个类实现一个或多个接口,实现的接口方法(重载)必须声明为public,若没有实现全部接口方法则必须声明为抽象类,接口实现的格式(尖括号仅限定格式,代码里面不需要):
1 | |
可以把接口的子类赋给接口的引用,但不能直接实例化接口,可以通过接口的引用调用由子类实现的接口方法。
类与包和访问权限
Object类:Java所有其他类都是Object类的子类。其方法有:略过。
包是类的容器,用来保存划分类名空间。
Java包含以下一个或几个:
- 单个接口声明(可选)
- 任意书面的引入语句(可选)
- 单个公共类声明(必须)
- 对包来说是私有的任意数目的类(可选)
定义包,以package命令作为Java源文件的第一句即可,该文件的任何类都属于指定的包,若package语句被省略则类名被输入到一个默认的没有名字的包,语句格式:
package pkg;
pkg是包名,可以是多层次的,如"java.awt.image"等,这表明该包的类必须保存在"java/awt/image"中。
类路径为"包名"+"."+"类名"。
类和包都是封装和容纳名称空间和变量及方法的措施。
- public的内容可以从任何地方访问
- protected的内容仅对不同的包中的非子类不可见
- 默认级,对不同包中的类不可见
- private的内容仅在同一类中可见
在Java源程序中import语句紧接着package语句,且在任何类的定义之前,格式:import pkg.classname
classname要正确指定或者使用'*'字符以导入所有类。
包是特殊的类,是类的容器,因此类是包的成员,可以用完整的类路径使用类而无需导入包。
异常处理
异常是一个描述代码段中发生异常情况的对象。
当异常发生,一个代表该异常的对象被创建并在导致该错误的方法中被引发。该方法可以自己处理或传递异常。
Java异常处理关键字:
"try","catch","throw","throws","finally"
其形式如下:
1 | |
ExceptionType是要捕获异常的类型,所有异常都是内置类Throwable的子类,Throwable位于异常类的顶层,其有两个分支Exception和Error,在Exception分支上,有一个重要子类RuntimeException,Error定义了通常情况下不希望程序捕获的异常,Error异常用于Java运行时与系统本身有关的错误(如堆栈溢出)。
默认异常处理:对于未被捕获的异常,Java执行系统的默认捕获,其显示一个描述异常的字符串,打印异常发生的堆栈轨迹并终止程序。
异常捕获:为防止或处理一个运行时异常,只需要把要监控的代码放入try块,一旦发现异常将直接转到对应的catch块中(被捕获)。执行不会从catch块返回try块,一个try和它的catch语句形成了一个单元,一个catch语句不能捕获其他try声明所引发的异常(除非是嵌套try语句),try不能单独使用。
finally语句,在异常或无异常的情况下都会执行的块。
finally创建的块在一个try/catch块完成之後另一个try/catch块出现之前执行,finally块即是函数返回,也会在返回之前被执行,即使try块中有return语句,也会在try块结束前执行finally块中的语句。
Throwable重载了toString()方法以返回一个包含异常描述的字符串。可以使用多重catch语句,但异常子类的catch块必须在其父类之前,否则是不能到达的代码错误。
try块可以嵌套,可以很隐蔽的形成,如方法调用放在try块中而方法内有另一个try语句。
用throw引发明确的异常,语句如下:
throw ThrowableInstance;
Throwable可以在catch子句中使用参数或new操作符创建,所有Java运行内置异常有两个构造函数:无参和带字符串参数。
如果一个方法可能导致异常但不处理它,那么应该在方法的声明後加上throws语句以明确可能会发生的异常,形式如下:
1 | |
exception_list是该方法可能引发的异常列表(以逗号分隔)。
输入输出
文件操作
- 作者:杨玉军 ↩