final关键字的用法

1.final数据
指编译时常量,或者一旦赋值就不允许被改变的数据。如果是编译时常量,就要用static和final修饰,常量名大写,单词与单词之间用_隔开。final数据必须是基本数据类型。
private static final int MAX_VALUE = 15;

2.final引用
如果final修饰的是一个对象,它并不是指对象是不可变的,而是存储对象的内存地址是不可变的
public void timerTask() {
        final TestA t = new TestA();
        t.setName("liyc");
        System.out.println(t.getName());
        t.setName("gzslyc333");
        System.out.println(t.getName());
	}

尽管t是被final修饰,但是t内部的属性是完全可以改变的。

3.空白final

空白final指允许在一个类中存在没有被赋值的final域,但该域必须在被使用前完成初始化,所以空白final一般在构造方法中完成初始化。

class TT{
	private final String name;
	public TT(String str) {
		this.name = str;
	}
}

这样的优势是方便动态的指定final数据。

4.final参数

final参数通常在匿名内部类中使用,参数在方法中不允许再重新赋值

public TT get(final String number) {
		return new TT() {
			public void say() {
				//number = "555";错误,静态参数接收外部值后不允许重新赋值
				System.out.println(number);
			}
		};
	}
同时结合final数据和final引用,如果final参数是基本数据类型,那么它一旦被赋值就不允许被改变。我们可以把final参数当作原数据的一个副本,所以哪怕方法体外原数据怎么改变,方法体内final参数都不会发生改变。比如
public class TestTimer {
	public void timerTask() {
		int a = 666;
		TT t = new TT().get(a);
		t.say();
		a=555;
		t.say();		
	}
}
class TT{
	public void say() {}
	public TT get(final int number) {
		return new TT() {
			public void say() {
				//number = "555";错误,静态参数接收外部值后不允许重新赋值
				System.out.println(number);
			}
		};
	}
}

根据上面的结论,我们可以知道输出结果为666和666,而非666和555。
那么同理,如果final参数是一个对象,它只是指存储对象的地址不变而已,对象内部是可以变化的,方法体内部也会随着对象改变而改变,比如

public class TestTimer {
	public void timerTask() {
		TestA test = new TestA();
		test.setName("55开");
		TT t = new TT().get(test);
		t.say();
		test.setName("pdd");
		t.say();
	}
}
class TT{
	public void say() {}
		public TT get(final TestA t) {
		return new TT() {
			public void say() {
				//number = "555";错误,静态参数接收外部值后不允许重新赋值
				System.out.println(t.getName());
			}
		};
	}
	
}

这次的输出结果为55开和pdd了。

5.final方法

final方法指不可以被重写的方法。

6.final类
指不可以被继承的类。但是final类中的域可以根据自己的意愿设定它们是否为final,不过方法则都是隐式声明为final的,毕竟final类不可以被继承,其中的方法自然也不能被重写了。

猜你喜欢

转载自blog.csdn.net/qq_26950567/article/details/80393798