零基础学Java,肝了bilibili的6百多集JavaSE教程传送门的学习笔记!!!
下面博客分为两部分:
1、final是Java语言中的一个关键字。
2、final表示最终的,不可变的。
3、final可以修饰变量以及方法,还有类等。
4、final修饰的变量?
final修饰的变量只能赋一次值。
final修饰的引用一旦指向某个对象,则不能再重新指向其它对象,
但该引用指向的对象内部的数据是可以改变的。
* final修饰的实例变量必须手动初始化,不能采用系统默认值。
* final修饰的实例变量一般和static联合使用,称为常量。
5、final修饰的方法?—— 无法被覆盖、被重写。
6、final修饰的类?—— 无法被继承
被final修饰的类无法被继承,编译时会报错。
XiaoMing类被无情地…成了太监,就不会有派生类了。
final class XiaoMing {
}
public class FinalTest01 extends XiaoMing {
}
重写final修饰的方法,编译时出现异常
‘doSome()’ cannot override ‘doSome()’ in
‘com.java.keywordsFinal.XiaoHei’; overridden method is final
class XiaoHei {
public final void doSome() {
System.out.println("Xiaohei doSome...");
}
}
public class FinalTest02 extends XiaoHei {
public void doSome() {
System.out.println("FinalTest02 doSome...");
}
public static void main(String[] args) {
FinalTest02 finalTest02 = new FinalTest02();
finalTest02.doSome();
}
}
final修饰的变量一经赋值,不可更改!
public class FinalTest03 {
public static void main(String[] args) {
final int a;
a = 100;
// a = a % 10;
// Variable 'a' might already have been assigned to
System.out.println("final int a: " + a);
}
}
final修饰的变量,如果这个变量是一个“引用”会怎样?
final修饰的引用:
① 该引用只能指向一个对象,并且永远指向该对象,无法再指向其它对象。
② final修饰的引用指向的对象不能换,但是此时Person对象内部的数据可以修改。
Cannot assign a value to final variable ‘person1’
不能分配一个值给final变量’person1‘
class Person {
int age;
public Person() {}
public Person(int age) {
this.age = age;
}
}
public class FinalTest04 {
public static void main(String[] args) {
Person person = new Person(20);
System.out.println(person.age);
final Person person1 = new Person(30);
// person1 = new Person(40);
// person1 = person;
// person1 = null;
// Cannot assign a value to final variable 'person1'
person1.age = 99; // 可以修改内部的值
System.out.println(person1.age);
}
}
注意:实例变量如果没有手动赋值的话,系统会赋默认值。
final修饰的实例变量,系统不负责赋默认值,程序员在编写类的时候要手动赋初始值,不然编译报错。
User类
class User {
// 实例变量
int a;
// 1、
// final int age; // 报错
// Variable 'age' might not have been initialized
// 2、手动默认初始值
final int age = 100;
// 3、依靠非final修饰的实例变量赋值 - 也就是用a给id赋值
final int id = a;
// 4、在构造器中赋值
final int no;
// 4.1、无参数构造器里默认值
public User() {
this.no = 80;
}
// 4.2、有参数构造器里使用形参赋值
public User(int a,int no) {
this.a = a;
this.no = no;
}
}
实验类
public class FinalTest05 {
public static void main(String[] args) {
User u1 = new User();
System.out.println("u1.id: " + u1.id);
User u2 = new User(18, 20);
System.out.println("u2.id: " + u2.id);
/*运行结果:
u1.id: 0
u2.id: 0
是不是很疑惑啊,这就是以前的老知识点了,这里不解释。
*/
}
}
实例变量在什么时候赋值(初始化)?
构造方法执行的过程中赋值。(new的时候赋值)
之前学过,类如果没有编写构造器方法时,系统会自动生成默认构造器方法,
但是这个默认构造器方法不会给final修饰的实例变量赋初始值,这也是 "例1"报错的原因。
而当我们自己编写构造器的时候,如果不编写 对final修饰变量赋值 的代码,
编译器也是会报错的。
final修饰的实例变量一般添加static修饰,变为静态,存储在方法区
public class FinalTest06 {
public static void main(String[] args) {
System.out.println(Chinese.COUNTRY);
}
}
class Chinese {
String idCard;
String name;
// final String country = "中国";
// 既然这里的值不会改变,还有必要声明为实例变量吗?
// 实例变量的缺点:占空间(100个对象,100份实例变量)。
// 实例变量既然用final修饰了,那就不会随对象的变化而变化。
public final static String COUNTRY = "中国";
// 常量一般是公开的。
// final static,声明100个Chinese类对象,只会占用一份COUNTRY的内存空间
}