本文共 3902 字,大约阅读时间需要 13 分钟。
使用同样的命名来定义不同的方法,只要参数不同(即签名不同)。
Java编译器根据方法签名决定使用哪个方法:public class Main { public static void main(String[] args) { initData(100, 10); initData(3.14, 2.9); } // 整数类型 public static void initData(int x, int y) { System.out.println("x: " + x); System.out.println("y: " + y); } // 浮点数类型 private static void initData(double x, double y) { System.out.println("x: " + x); System.out.println("y: " + y); }}
静态方法可使用"类名.方法名"调用,或"对象名.方法名"调用,(调用方式同Python相同)
实例方法可使用"对象名.方法名"调用代码块就是用大括号({})将多行代码封装在一起,形成一个独立的数据体,用于实现特定的算法。
public class Test { public void test(){ System.out.println("普通代码块"); }}
public class Main { static int cnt = 6; static { cnt += 9; } public static void main(String[] args) { System.out.println(cnt); // 显示5 } static { cnt /= 3; }}
静态代码块的注意:
1、它是随着类的加载而执行,只执行一次,并优先于主函数。具体说,静态代码块是由类调用的。类调用时,先执行静态代码块,然后才执行主函数的。 2、静态代码块其实就是给类初始化的,而构造代码块是给对象初始化的。 3、码块中的变量是局部变量,与普通函数中的局部变量性质没有区别。 4、一个类中可以有多个静态代码块同步代码块
使用 synchronized 关键字修饰,并使用“{}”括起来的代码片段,它表示同一时间只能有一个线程进入到该方法块中,是一种多线程保护机制构造代码块
在类中直接定义没有任何修饰符、前缀、后缀的代码块即为构造代码块.编译器会将代码块按照他们的顺序(假如有多个代码块)插入到所有的构造函数的最前端,这样就能保证不管调用哪个构造函数都会执行所有的构造代码块
只有实例化对象时直接调用的构造函数才会执行一次构造代码块:public class Main { { // 构造代码块 System.out.println("执行构造代码块1..."); } public Main(){ this("1245"); System.out.println("执行无参构造函数..."); } public Main(String id){ System.out.println("执行有参构造函数..."); } public static void main(String[] args) { Main cc = new Main(); Main cc2 = new Main("1234"); } { // 构造代码块 System.out.println("执行构造代码块2..."); }}/* output:执行构造代码块1...执行构造代码块2...执行有参构造函数...执行无参构造函数...执行构造代码块1...执行构造代码块2...执行有参构造函数...*/
构造代码块使用场景:
1、 初始化实例变量:多个函数都需要初始化实例变量时,应将该变量放入构造代码块
2、初始化实例环境:将创建对象的存在环境的代码封装到构造代码块,提升构造函数的可读性
关于构造代码块,以下几点要注意:
1、构造代码块的作用是给对象进行初始化。
2、对象一建立就运行构造代码块了,而且优先于构造函数执行。这里要强调一下,有对象建立,才会运行构造代码块,类不能调用构造代码块的,而且构造代码块与构造函数的执行顺序是前者先于后者执行。 3、构造代码块与构造函数的区别是:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。
顺序: 静态代码块 > 构造代码块 > 构造函数
public class Main { public static void main(String[] args) { new InitialOrderTest(); }}class InitialOrderTest { /* 静态变量 */ public static String staticField = "静态变量"; /* 实例变量 */ public String field = "实例变量"; /* 静态初始化块 */ static { System.out.println( staticField ); System.out.println( "静态初始化块" ); } /* 构造代码块 */ { System.out.println( field ); System.out.println( "初始化块" ); } /* 构造方法 */ public InitialOrderTest() { System.out.println( "构造方法" ); }}/* output静态变量静态初始化块实例变量初始化块构造方法*/
子类从父类中继承方法,而子类需要修改父类中定义的方法的实现,这就是方法重写
public class Main { public static void main(String[] args) { SubBase cc = new SubBase(); cc.f(); }}class Base { public void f() { System.out.println("Base"); }}class SubBase extends Base { public void f() { // 子类重写父类的f方法,父类的方法被屏蔽掉 System.out.println("SubBase"); }}
注意:
1、仅当实例方法是可访问时,才能被重写。因为private方法在类外是不能访问,不能继承的,所有不可能被覆盖。
2、静态方法可被继承,但不能被覆盖。父类定义的静态方法在子类被重新定义为新静态方法,父类的静态方法将被隐藏,使用"父类名.静态方法名"可调用隐藏的静态方法。
throw : 该关键字用于主动抛出异常
try … catch: 捕获后处理异常 throws: 声明方法可能抛出异常,使用方式"throws 异常类" ,主要是告诉其它程序方法可能会抛出的异常1、throws的作用,声明一个函数可能会产生异常,但是我们在这个函数里面不处理, 而且由调用这个函数的对象进行异常try…catch…finally…
2、throw抛出的非运行时异常(继承自Exception的异常)需要throws声明在方法上 3、throw抛出运行时异常(继承自RuntimeException的异常)不需要throws声明在方法上
try { ... new ArithmeticException("Divisor cannot be zero")// throw语句直接抛出异常,或调用一个可能抛出异常的方法 ...}catch (ArithmeticException ex) { /*type:可捕获的异常类型;ex:保存异常抛出后的值*/ // 执行异常处理代码}
将检测错误(由被调用的方法完成)从处理错误(由调用方法完成)中分离处理:方法抛出一个异常,由由调用者决定是否终止程序。
1、没有处理的异常会沿着方法调用链向上传递,最终没有被捕获则会终止程序
2、父类中没有声明异常的方法,不能在子类中对其进行继承来声明异常
转载地址:http://gwerb.baihongyu.com/