首页 技术 正文
技术 2022年11月9日
0 收藏 931 点赞 2,280 浏览 3217 个字

  final修饰的类不可以有子类,例如:java.lang.Math类就是一个final类,它不可以有子类

子类继承父类,可以访问父类的内部数据,可以重写父类的方法来改变父类方法的实现细节,可能导致不安全因素:为了保证某个类不可被继承,则可以使用fianl修饰这个类,

代码示例:

public final class FinalClass{}

//下面的类定义将出现错误

class Sub extends FinalClass{}

FinalClass为final类,不能被继承,编译错误

=======================================================================================================================================

  final之不可变类

  不可变类(immutable)类的意思是创建该类的实例后,该实例的实例变量是不可改变的,java提供的8个包装类和java.lang.String类都是不可变类,当创建它们的实例后,其实例的实列变量都是不可改变的.

代码示例:

  Double d=new Double(8.56);  

  String str=new String(“Hello”);\

  创建的Double和`String实例,传入6.5和”Hello”字符串作为参数,Doule类和String类肯定都需要提供实例变量来保存这两个参数,但是程序无法修改这两个实例变量的值,Double和String类都没有提供修改它们的方法.

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

1.使用private和final修饰符来修饰类的成员变量

  2.提供带参数构造器,用于根据传入参数来初始化类里的成员变量.

  3.仅为该类的成员变量提供getter方法,不要为该类的成员提供setter()方法,因为普通方法无法修改final修饰的成员变量.

  4.如果有必要,重写Object类的hashCode()和equals()方法(详情讲义301),equals()方法根据关键成员变量来作为两个对象是否相等的标准,除此之外,还应该保证两个用equals()方法判断为相等的对象的hashcode()也相等.java.lang.String这个类做的很好,它就是根据String对象里的字符序列来作为相等的标准,其hashCode()方法也是根据字符序列计算得到的,

代码示例:

   package com.j1803.finalTest;
 
   public class ImmutableStringTest {

        public static void main(String[] args) {
        String str1=new String(“hellow”);
        String str2=new String(“hellow”);
        
        System.out.println(str1==str2);
        System.out.println(str1.equals(str2));
        
        //下面输出两次的hashCode相同
        System.out.println(str1.hashCode());
        System.out.println(str2.hashCode());

      }

  }

  answer:

  false
  true
  -1220935195
  -1220935195

  与不可变类对应的是可变类,可变类的含义是该类的实例变量是可变的,大部分时候所创建的类都是可变类,特别是JavaBean,因为总是为其实例变量提供了setter和getter方法.

  前面介绍了final修饰引用类型变量时,仅仅只是表示这个引用类型变量不可被重新赋值,但引用类型变量所指向的对象依然可以改变,这就产生了一个问题,当创建一个不可变类时,如果它包含成员变量的类型是可变的,那么其对象的成员变量的值依然是可改变的,这个不可变类其实是失败的.

代码示例:

package com.j1803.finalTest;

public class PersonTest {
    private final Name name;
    public PersonTest(Name name) {
        super();
        this.name = name;
    }
    public Name getName() {
        return name;
    }
    public static void main(String[] args) {
        
        Name n=new Name(“悟空”,”孙”);
        PersonTest p=new PersonTest(n);
        //PersonTest对象的name的firstName值为”悟空”
        System.out.println(p.getName().getFirstName());
        //改变PersonTest对象的name的firstName值
        n.setFirstName(“八戒”);
        //PersonTest对象的name的firstName值被改为”八戒”
        System.out.println(p.getName().getFirstName());
    }

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

answer:

悟空
八戒

代码修改:

public class PersonTest {
    private final Name name;
    public PersonTest(Name name) {
        super();
        //设置name实例变量为临时创建的Name对象,该对象的firstName和lastName;
        this.name=new Name(name.getFirstName(),name.getLastName());
    }
    public Name getName() {
        //返回一个匿名对象,该对象的firstName和lastName
        //与该对象里的name的firstName和lastName相同
        return new Name(name.getFirstName(),name.getLastName());
    }

answer:

悟空
悟空

  因此,如果设计一个不可变类,尤其要注意其引用类型的成员变量,如果引用类型的成员变量的类是可变的,就必须采取必要的措施来保护该成员变量所引用的对象不会被修改,这样才能创建真正的不可变类

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,492
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,495
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,133
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,297