JavaSE第二十三讲:static与final使用陷阱

public class StaticTest2
{
	public static void main(String[] args)
	{
	//MyStatic2 test = new MyStatic2();
	//test.output();
	MyStatic2.output();
	}
}

class MyStatic2
{
	public static void output()
	{
		System.out.println("output");
	}
}
执行结果:

D:\src>java StaticTest2
output


1. static 修饰方法:static 修饰的方法叫做静态方法。对于静态方法来说,可以使用类名.方法名的方式来访问。 

2. 静态方法只能继承,不能重写(Override)。这个时候是隐藏了父类的静态方法,没有发生重写。同时静态方法不能覆盖非静态的方法,非静态的方法不能覆盖静态方法。【注意:这种需求一般在实际开发工程中不存在,可能在面试题目中会出现】

没有static关键字

public class StaticTest3{
	public static void main(String[] args){
		M m = new N();
		m.output();
	}
}

class M{
	public void output(){
		System.out.println("M");
	}
}

class N extends M{
	public void output(){
		System.out.println("N");
	}
}
执行结果:

D:\src>java StaticTest3
N

有static关键字

public class StaticTest3{
	public static void main(String[] args){
		M m = new N();
		m.output();
	}
}

class M{
	public static void output(){
		System.out.println("M");
	}
}

class N extends M{
	public static void output(){
		System.out.println("N");
	}
}
执行结果:

D:\src>java StaticTest3
M

【说明】:这个时候是隐藏了父类的静态方法,没有发生重写,具体调用那个方法取决于m的类型,这个程序m的类型是M所以执行父类当中的方法.如果对以下程序 n的类型是N,所以执行N类中的静态方法。

例如修改上个程序第二行代码段

	public static void main(String[] args){
		N n = new N();
		n.output();
	}
则执行结果为:

D:\src>java StaticTest3
N


下面这个程序是为了验证静态方法是不能被重写的,用注释@Override来,编译程序报错。

public class StaticTest3{
	public static void main(String[] args){
		M m = new N();
		m.output();
	}
}

class M{
	public static void output(){
		System.out.println("M");
	}
}

class N extends M{
	@Override
	public static void output(){
		System.out.println("N");
	}
}
编译结果:

D:\src>javac StaticTest3.java
StaticTest3.java:15: 错误: 方法不会覆盖或实现超类型的方法
        @Override
        ^
1 个错误

【说明】:注释@Override是为了告诉编译器我要对这个方法进行重写,而静态方法是不能被重写的显然报错。


3. final关键字:final可以修饰属性方法、类。用fianl之后就不能去动它了简单讲就是这样。

4. final修饰类:当一个类被final所修饰时,表示该类是一个终态类,即不能被继承。

public class FinalTest{
	public static void main(String[] args){
	}
}

final class E{
}

class F extends E{
}

编译结果:

D:\src>javac FinalTest.java
FinalTest.java:9: 错误: 无法从最终E进行继承
class F extends E{
                ^
1 个错误


5. final修饰方法:当一个方法被final所修饰时,表示该方法是一个终态方法,即不能被重写(Override)。

public class FinalTest2{
	public static void main(String[] args){
		H h = new H();
		h.output();
	}
}

class G{
	public final void output(){
		System.out.println("G");
	}
}

class H extends G{
	public void output(){
		System.out.println("H");
	}
}
执行结果:

 D:\src>javac FinalTest2.java
FinalTest2.java:15: 错误: H中的output()无法覆盖G中的output()
        public void output(){
                    ^
  被覆盖的方法为final
1 个错误


6. final修饰属性:当一个属性被final所修饰时,表示该属性不能被改写。 

public class FinalTest3{
	public static void main(String[] args){
		People people = new People();
		people.age = 20;
	}
}

class People{
	final int age = 10;
}
执行结果:
D:\src>javac FinalTest3.java
FinalTest3.java:4: 错误: 无法为最终变量age分配值
                people.age = 20;
                      ^
1 个错误 

【说明】:当age用final来修饰的时候,此时age不能再变化了,相当于age是一个常量了。


继续修改程序

public class FinalTest3{
	public static void main(String[] args){
		People people = new People();
	//	people.age = 20;
		people.address = new Address();	
	}
}


class People{
	//final int age = 10;
	final Address address = new Address();
}

class Address{
	String name = "Beijing";
}
编译结果:

D:\src>javac FinalTest3.java
FinalTest3.java:5: 错误: 无法为最终变量address分配值
                people.address = new Address();
                      ^
1 个错误

【说明】:此时错误的原因是final修饰的address指向的对象被修改了,所以程序出现错误。如图22-2所示。

图22-2

继续修改程序:

public class FinalTest3{
	public static void main(String[] args){
		People people = new People();
	//	people.age = 20;
	//	people.address = new Address();	
		people.address.name = "shanghai";
	}
}


class People{
	//final int age = 10;
	final Address address = new Address();
}

class Address{
	String name = "Beijing";
}

编译结果成功

【说明】:此时final关键字修饰的引用没有被修改,修改的只是指向的这个对象的值被修改了,所以final修改的这个指向地址是没有变化的,所以程序编译成功。如图22-3所示。

图22-3

7final修饰一个原生数据类型时,表示该原生数据类型的值不能发生变化比如说不能从10变为20);如果final修饰一个引用类型时,表示该引用类型不能再指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值