`
瘋叻ハ.兩
  • 浏览: 80614 次
  • 性别: Icon_minigender_1
  • 来自: 宁德
社区版块
存档分类
最新评论

final,助你排除不稳定

 
阅读更多

      【友情提示,想看懂本篇请熟悉类的变量的分类、方法重载、重写及相关内容】

 

      final关键字,正如它的英文释义-- 不可更改的,所以被它修饰的属性或者方法一旦确定下来,就不能更改了。鉴于它的整个特性,所以常常我们以之定义常量属性、定义不可被重写的父类方法、不可改变的类。

 

      我们知道,Java中的变量可以分为成员变量和局部变量(不清楚分类的可点击:Java起航 -- 类的变量 ),方法就没有比较本质的区别(方法作为形参暂不考虑,有机会后面会提到);我们也知道Java中是不能使用未初始化的变量。也许有童鞋会疑问,当我们在方法中使用未初始化的变量怎么就不报错?如

class A{
    private  int salary;    //未初始化怎么可以正常编译及使用

    public int getSalary(){
          return salary;
    }
}

 

这时,我们就要抛出一个“定理”就能解释了:Java的编译器只会对非final修饰的成员变量执行默认初始化,赋予默认值,而不会对final成员变量执行默认初始化,至于局部变量,至始至终就不会进行默认的初始化(不得不说它是个可怜的娃...),所以你现在就能明白上面的程序是怎么回事,打印方法结果会得到一个0,至于结论,自己总结!

      为了使被final修饰的变量可以正常使用,但又不能依靠编译器默认初始化,所以只能自己动手让它显式初始化。以下是各种变量初始化的时机:

      final修饰的类属性的初始化方式有:要么声明时直接赋值,要么在静态初始块中初始化;

      final修饰的对象属性的初始化方式有:要么声明时直接赋值,要么非静态初始块或者构造器中;

      final修饰的方法内部的局部变量: 直接或者间接声明时初始化。

      final修饰的方法形参的局部变量: 初始化过程参考形参初始化(页面底部)中的方法传递,但注意不能再在方法内对形参赋值         

      final修饰的代码块的局部变量: 与方法内部的局部变量一致。

      如果你对上面存有疑惑,那么你再记住这一句话:一旦被初始化就不能再被赋值关于上面的言论,个人就不贴出代码了,如果有“基础”的你,我相信你绝对可以翻译成测试程序的。

 

      如果final修饰了基本类型的变量,那么这个变量与局部变量如同一撤,但是final修饰了对象的引用变量,就可以修改改变量的值,如

class B{
    private int age;
    
    public B( int a ){
        age = a;
    }

    public int getAge( ){
        return this.age;
    };
 
    public void setAge( int temp){
        this.age = temp;
    }
    
    public static void main(String[] args){
        // use final to declare the B object
        final B b = new B(15);
        System.out.println(b.getAge()); // print 15

        b.setAge(20);
        System.out.println(b.getAge()); // print 20
    }

}

 

 

      至于final修饰的方法,只能被重载,而不能被重写。我们可以这么理解这句话:被重载的方法通过形参列表的不同可以标识出每个方法的唯一性,但是重写,只是对方法的执行体进行修改,并没有对方法的唯一标识进行修改(方法的唯一标识可以从调用方法的过程总结:调用方法的过程(页面底部);但是我们又从final关键字得到浓浓的唯一味道,所以我们很能理解方法可以被重载但不能被重写。

      

      被final修饰的类不能有子类,至于缘由,个人可仿照方法进行推演找出总结的答案。下面着重介绍不可变类。

 

 

      不可变类(immutable class),是指创建的实例不能重新对实例的属性进行重定义,比如String

// create String object
String peo = new String("people");

// peo.setValue("hello");   won't work.

 

      如果要创建自定义的不可变类,可遵守如下规则:

      1、类中定义的属性建议被private修饰、但必须被final修饰。private是封装性,final是不可变性

      2、对属性可以提供getter方法,但不能定义setter方法,即使定义了也会报编译错误。

      3、必须具有完整的有参构造,其作用是根据传入的参数对属性执行初始化

      4、有选择的重写Object类的hashCode和equals方法。


       相关代码

package com.Immutable;

/**************************************************
 * simply define a immutable class.   【 群:152380972 】                                
 * @author:      瘋叻ハ.兩                                                                              
 * @revision:    1.0                                                        
 * @create-time: 2011-9-12 下午04:26:15                                               
 ***************************************************/
// immutable class extends Object class defaultly. 
public class ImmutableTest1 {

	// declare variables
	private final String name;
	private final int age;
	
	// construtor with fields
	private ImmutableTest1(String name, int age) {
		this.name = name;
		this.age = age;
	}

	// getters
	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}
	
	// override equals and hashCode from Object
	@Override
	public boolean equals(Object obj){
		if( obj instanceof ImmutableTest1){
			if(this.getName().equals(((ImmutableTest1) obj).getName())){
				System.out.println(1);
				return true;
				
			}
			System.out.println(2);
			return false;
			
		}
		System.out.println(3);
		return false;
	}
	
	@Override
	public int hashCode() {
		return name.hashCode();
	}
	public static void main(String[] args){
		ImmutableTest1 it1 = new ImmutableTest1("张三", 19);
		ImmutableTest1 it2 = new ImmutableTest1("张三", 19);
		System.out.println(it1.equals(it2));
		System.out.println(it1.name.hashCode());
		System.out.println(it2.name.hashCode());
		
	}
	
}

 

       运行结果

                   1
                   true
                   774889
                   774889

 

         分  析  :看代码注释

     

      上面的结论告诉了我们按上述要求定义的类是不可变类。假如不可变类中的final属性是组成了一个普通的类,情况又会怎样呢?且看如下代码
       相关代码

/**************************************************
 * make up a immutable class with a common class.  【 群:152380972 】                                
 * @author:      瘋叻ハ.兩                                                                              
 * @revision:    1.0                                                        
 * @create-time: 2011-9-12 下午04:47:06                                               
 ***************************************************/
public class ImmutableTest2 {

	public static void main(String[] args) {
		Name n = new Name("悟空","孙");
		Person p = new Person(n);
		System.out.println("改前是:" + p.getName().getFirstName());
		
		// reset firstName
		n.setFirstName("八戒");
		System.out.println("改后是:" + p.getName().getFirstName());

	}
}
// immutable class
class Person{
	final Name name;
	
	public Person(Name n){
		this.name = n;
	}
	
	public Name getName(){
		return this.name;
	}
}

// simple class
class Name{
	private String firstName;
	private String lastName;
	
	public Name(String fir, String las){
		this.firstName = fir;
		this.lastName = las;		
	}
	
	public String getFirstName() {
		return firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
}

       运行结果

                    改前是:悟空
                    改后是:八戒

 

         分  析  :把组成的类看成是一个引用变量则结果就一目了然了

 

      从上述结果我们看到了Person类被破坏了。为了保护Person类的属性的不可变,我们只需将Person类改动如下代码:

// immutable class
class Person{
	final Name name;
	
	public Person(Name n){
		this.name = new Name(n.getFirstName(), n.getLastName());
	}
	
	public Name getName(){
		return new Name(name.getFirstName(), name.getLastName());
	}
}

 

本篇有点细点我解释的不是很清楚,如果有人懂的还好,但是不懂的请回头耐心的复习基础,程序员是要有基本的思考能力和耐心,很多时候程序员是把抽象的思路变成可行的路! 请相信,我行的...

      

 

 

0
2
分享到:
评论

相关推荐

    Netty 3.6.2.Final 稳定版本 含源码

    Netty 3.6.2.Final 稳定版本 含源码

    Final IK 1.9 Final IK 1.9

    Final IK 1.9

    Final Cut Studio 2.0

    Final Cut Studio 2让你超越纯粹的剪辑。你将发现特别为 Final Cut Pro 用户设计的新创意工具的强大力量。从剪辑快速过度到动画制作、音频编辑及混音、颜色分级以及作品交付——所有这些都是你所熟悉的工作的自然...

    Final IK 2.2 - Unity

    Final IK 2.2 - Unity

    FinalIK动画辅助制作工具

    FinalIK动画辅助制作工具骨骼,IK

    Final Draft 10.0.7

    Final Draft是世界上最畅销的剧本...这样一来,你就不需要再多花时间学习剧本的格式应该是什么规则,也不必担心剧本过于凌乱导致他人无法看明白了;Final Draft的价值就是自动为你转换格式成为世界通用的模式和标准。

    FinalData OEM V2.0 简体中文版

    微软的windows平台提供了回收站来保护那些你不小心删除的文件。在windows平台删除文件,这些文件首先会移动道回收站,如果需要,你可以从那里面恢复数据。 如果,你通过([Shift]-[Delete])等方式,没有删除到回收站...

    USB 3 0 Final USB 3 0 Final USB 3 0 Final

    USB 3 0 Final USB 3 0 Final USB 3 0 Final

    FinalData、FinalData

    FinalData是一个免费的带有中文界面的数据恢复软件,主要用于恢复误删除的文件。FinalData软件体积小,可以快捷、有效地恢复误删除的文件,FinalData提供了绿色版和安装版,绿色版可以放在U盘上使用。

    Hibernate稳定版(hibernate-release-5.3.23.Final.zip)

    Hibernate稳定版(hibernate-release-5.3.23.Final.zip),Hibernate ORM 是一个为应用程序、库和框架提供对象/关系映射 (ORM) 支持的库。它还提供了 JPA 规范的实现,这是 ORM 的标准 Java 规范。

    hibernate3.6.10.Final

    hibernate 3.6.10 Final版,稳定

    F13Final_13final_

    EE5806 year 2013 final

    validation-api-2.0.1.Final

    validation-api-2.0.1.Final 下载使用 ,需要的同学可以试试。有问题请留言。validation-api-2.0.1.Final 下载使用 ,需要的同学可以试试。

    final ik1.9下载

    1.9 版本对最终逆向运动学 (Final IK) 进行了很多修复和改进: - 增加了烘焙器,这是一个强大的新工具,可将 IK 烘焙到 Humanoid、Generic 和 Legacy 动画剪辑中。 - 将 LOD 级别添加至 VRIK。 - 已在新版 Oculus ...

    Final Effects汉化插件

    Final Effects汉化插件 Final Effects汉化插件 Final Effects汉化插件

    Final IK v1.7.unitypackage.zip

    Final IK v1.7.unitypackage The final Inverse Kinematics solution for Unity.

    JMOCK final class mock

    JMOCK final class mockJMOCK final class mockJMOCK final class mockJMOCK final class mockJMOCK final class mock

    FinalData

    FinalData

    Final Data

    FinalData就是通过这个机制来恢复丢失的数据的,在清空回收站以后也不例外。另外,FinalData可以很容易地从格式化后的文件和被病毒破坏的文件恢复。甚至在极端的情况下,如果目录结构被部分破坏也可以恢复,只要数据...

    FinalData_2.01

    FinalData就是通过这个机制来恢复丢失的数据的,在清空回收站以后也不例外。另外,FinalData可以很容易地从格式化后的文件和被病毒破坏的文件恢复。甚至在极端的情况下,如果目录结构被部分破坏也可以恢复,只要数据...

Global site tag (gtag.js) - Google Analytics