final集锦

final 可以定义在接口、类、方法、变量上,根据定义的位置不同,作用也不尽相同。

当final作用在接口上                                                   

在接口中定义的信息即为公共,即所以实现接口的类都具有相同的属性。对应外部调用时,返回的效果也应该是一致的。

所以,在接口上定义的变量值,默认类型就是public static final的,它不允许实现类擅自修改变量的值。

public interface Hello{
	//接口定义变量时,默认类型就是
	//public static final
	String name = "Amkio" ;
}
public static void main(String[] args) {	
    System.out.println("Hello " + Hello.name);
}


当实现类尝试修改接口上的变量值时,编译器给出了错误提示 

Multiple markers at this line

- The final field Hello.name cannot be assigned

- The static field Hello.name should be accessed in a 

static way

public class HelloWorld {
  //这里在编译器中会报错
  public void setName(String name) {
    this.name = name ;    
  }

  public interface Hello{
    String name = "Amkio" ;
  }



当final作用在Class上                                                    

在类定义上添加final关键字后,即表示不允许有子类出现!!(断子绝孙了~~~~~)

The type HelloJava cannot subclass the final class  HelloWorld

public final class HelloWorld  {
	private String name = null ;
	public void setNameA(String name) {
		this.name = name ;
	}
}
//这里在编译器中会报错
class HelloJava extends HelloWorld{}  



当final作用在方法上                                                        

在方法的返回类型前添加上final,即表示该方法在子类中不允许修改。

public class HelloWorld  {

	public String name = null ;
	public final void setNameA(String name) {
		this.name = name ;
		
	}
}

class HelloJava extends HelloWorld{
//这里在编译器中会报错,因为父类中该方法已经设置为final,即表示不允许子类修改。
	public void setNameA(String name) {
		this.name = "AAAA" ;
	}
}

当final作用在变量上                                                           


即常量,这一种是我们最常使用的,此处省略几百字。。。。。。。

public final class HelloWorld  {
    private String name = null ;
    
    public static void main(String[] args){
        System.out.println(HelloWorld.name);
}


}
 
final常量的初始化                                                              

常量变量只能初始化一次,但是。。。。却有两种方法:
1. 一般是在定义变量的时候即赋值。参考 public final int A=0

2. 如果有特殊要求,例如:来自配置文件、来自入参、需要计划等,可以通过构造器来完成初始化


public class HelloWorld  {

	public final int A = 0;
	public final int B ;
	
	public HelloWorld() {
		B = 2 ;
	}
}



final静态常量的初始化                                                              

静态常量也是常量,所以也只能初始化一次,但是。。。。也有两种方法:
1. 一般是在定义变量的时候即赋值。参考 public static final int B=0

2. 如果有特殊要求,例如:来自配置文件、来自入参、需要计划等,可以通过静态块完成。 

public class HelloWorld  {

	public static final int A ;
	public static final int B =0;
	static {  //静态块
		A = 1 ;
	}
	
}


当final作用在参数上                                                              


在一个方法的入参上添加final关键字,表示该参数的数值不允许在方法内被改变。对于大多数的场景下,此做法没有什么必要的用处,因为在java的传参过程中,大多数都传的是只是值。所以,不会影响调用者的值发生改变。

public class HelloWorld  {

	public String name = null ;
	public void setNameA(final String name) {
		this.name = name ;
		//这里在编译器中会报错
		//The final local variable name cannot be assigned. It must be blank and not using a compound assignment
		name = "abc" ;
		
	}
}

接下来,有个奇怪的事情发生了,我写了这样一段代码,但是结果却超出了我的预期~~~~~~~难过

public class HelloWorld{

	public String name = null ;
	
	public void setName(final char[] name) {
		this.name = String.valueOf(name) ;
		name[0] = '2' ; //这里没报错~~~~~
		
	}
	
	public static void main(String[] args) {
		HelloWorld hello = new HelloWorld();

		char[] c = {'A','m','k','i','o'} ;
		
		hello.setName(c);
		
		System.out.println(String.valueOf(c));
	}
}

输出结果:

1mkio

2mkio

为什么会这样呢。。。。。。。。。。。。。

因为这里的name指的是实参的地址的拷贝,你可以通过它修改这个地址的内容,因为此时这个内容的地址和原地址是同一地址,但是地址本身没有发生改变。

如果将上面的name[0] = '2' ; 改成 char[] ab= {'a','b'}; name = ab ; 会怎么样呢??

"The final local variable name cannot be assigned. It must be blank and not using a compound  assignment"

"remove 'final' modifier of 'name'"

完!!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值