Java中final作用于变量、参数、方法及类该如何处理

2025-05-27 0 37

Java方法用final修饰参数的作用

方法参数前面加final关键字就是为了防止数据在方法体重被修改。

主要分为两种情况:第一,用final修饰基本数据类型;第二,用final修饰引用数据类型。

第一种情况,修饰基本数据类型,这时参数的值在方法体内是不能被修改的,即不能被重新赋值。否则编译就不通过。

第二种情况,修饰引用类型。这时参数变量所引用的对象是不能被改变的。但是对于引用数据类型,如果修改其属性的话是完全可以的。

所以,final这个关键字,想用的话就用基本数据类型,还是很有作用的。

final变量

对于基本类型使用final:它就是一个常量,数值恒定不变

对于对象引用使用final:使得引用恒定不变,一旦引用被初始化指向一个对象,就无法再把 它改为指向另一个对象。然而,对象自身却是可以被修改的,java并没有提供使任何对象恒定不变的途径。这一限制同样也使用数组,它也是对象。

例子:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53
class Value{

int i;

public Value(int i){

this.i = i;

}

}

public class FinalData {

private static Random random = new Random(47);

private String id;

public FinalData(String id){

this.id = id;

}

private final int valueOne = 9;

private static final int VALUE_TWO = 99;

public static final int VALUE_THREE = 39;

private final int i4 = random.nextInt(20);

static final int INT_5 = random.nextInt(20);

private Value v1 = new Value(11);

private final Value v2 = new Value(22);

private static final Value VAL_3 = new Value(33);

private final int[] a = {1, 2, 3, 4, 5, 6};

public String toString(){

return id + ": " + "i4 = " + i4 + ", INT_5 = " + INT_5;

}

public static void main(String[] args) {

FinalData fd1 = new FinalData("fd1");

//! fd1.valueOne++; // 因为valueOne是基本类型常量,其数值恒定不变

fd1.v2.i++; //final修饰的对象的内容可以改变

fd1.v1 = new Value(9);

for(int i = 0; i < fd1.a.length; i++)

fd1.a[i]++;

//! fd1.v2 = new Value(0); // 因为v2是final修饰的引用类型,其引用不能被修改指向另一个对象

//! fd1.VAL_3 = new Value(1); // 表示占据一段不能改变的内存空间

//! fd1.a = new int[3]; // final修饰的数组

System.out.println(fd1);

System.out.println("Creating new FinalData");

FinalData fd2 = new FinalData("fd2");

System.out.println(fd1);

System.out.println(fd2);

}

}

/*output:

fd1: i4 = 15, INT_5 = 18

Creating new FinalData

fd1: i4 = 15, INT_5 = 18

fd2: i4 = 13, INT_5 = 18

*/

分析:

对于fd1,fd2两个对象,其中i4是唯一的,即每个对象都有一个i4,但INT_5被声明为static,即是类共享的,fd1和fd2共享INT_5,在装载时已经被初始化,而不是每次创建新对象时初始化(例如i4);但它同时被设置成final,所以它的引用是不可改变的,即不能被修改指向另一个对象。

空白final:

被声明为final但又没有给定初值。必须在域的定义或者每个构造器中使用表达式对final进行赋值,这正是final域在使用前总是初始化的原因。

final参数

这意味着你无法在方法中更改参数引用,使其指向另一个参数,但可以修改final对象所指向的内容

例子:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25
class Gizmo{

int i = 0;

public void spin(){}

}

public class FinalArguments {

void with(final Gizmo g){

//! g = new Gizmo(); // 无法修改final修饰的引用,使它指向另一个对象

g.i++; // 但可以修改final对象所指向的内容

}

void without(Gizmo g){

g = new Gizmo();

g.spin();

}

// int g(final int i){

// //! i++; //因为参数i是常量值

// }

int g(final int i){

return i + 1;

}

public static void main(String[] args) {

FinalArguments bf = new FinalArguments();

bf.without(null);

bf.with(null);

}

}

分析:

参数被声明为final,若是基本参数,那它就是一个常量,不能被修改;若是一个引用变量,那么它就不能被修改指向另一个对象,但可以修改该引用所指对象的内容。

fianl方法

使用原因:

  • 方法锁定,以防任何继承类修改它的含义,即该方法不会被继承的类覆盖
  • 效率,若一个方法指明为final,那么就同意编译器将针对该方法的所有调用转为内嵌调用。

类中所有的private方法都隐式地指定为final,由于无法取用private方法,所以也就无法覆盖它。可以对private方法添加final修饰词,但这并不会给该方法带来任何额外的意义。

例子:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49
class WithFinals{

private final void f(){

System.out.println("WithFinals.f()");

}

private void g(){

System.out.println("OverridingPrivate.f()");

}

}

class OverridingPrivate extends WithFinals{

private final void f(){

System.out.println("OverridingPrivate.f()");

}

private void g(){

System.out.println("OverridingPrivate.g()");

}

}

class OverridingPrivate2 extends OverridingPrivate{

/*

* 当使用Override注解强制使f()方法覆盖父类的f()方法时,会报错

* 因为它不知道父类是否有该方法,对于g()方法来说,它只是生成了一个新的方法,

* 并没有覆盖掉父类中的g()方法。

*/

//@Override

public final void f(){

System.out.println("OverridingPrivate2.f()");

}

public void g(){

System.out.println("OverridingPrivate2.g()");

}

}

public class FinalOverridingIllusion{

public static void main(String[] args) {

OverridingPrivate2 op2 = new OverridingPrivate2();

op2.f();

op2.g();

// 可以向上转型

OverridingPrivate op = op2;

//! op.f(); // 父类中final方法对子类来说是不可见的

//! op.g();

WithFinals wf = op2;

// wf.f();

// wf.g();

}

}

/*output:

OverridingPrivate2.f()

OverridingPrivate2.g()

*/

分析:

覆盖何时发生:

  1,子类中出现与父类完全一致的方法

  2. 子类可以通过向上转型为父类,并调用父类中的那个方法

若父类中某个方法被声明为final或者private,那么这个方法对子类来说是不可见的,就算在子类中创建了与父类一模一样的方法,这也是一个新的方法,而不是从父类中覆盖的方法

final类:

即该类不能被继承,不管是你还是别人,也就是这个类不需要做任何变动,也不需要任何子类,例如String类。

例子:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18
class SmallBrain{}

final class Dinosaur{

int i = 7;

int j = 1;

SmallBrain x = new SmallBrain();

void f(){}

}

// error: The type Further cannot subclass the final class Dinosaur

// Dinosaur类不能有子类

// class Further extends Dinosaur{}

public class Jurassic {

public static void main(String[] args) {

Dinosaur n = new Dinosaur();

n.f();

n.i = 40;

n.j++;

}

}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对快网idc的支持。

原文链接:http://www.cnblogs.com/aristole/p/8016448.html

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Java中final作用于变量、参数、方法及类该如何处理 https://www.kuaiidc.com/77254.html

相关文章

发表评论
暂无评论