final修饰符(6)-final类
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:
悟空
悟空
因此,如果设计一个不可变类,尤其要注意其引用类型的成员变量,如果引用类型的成员变量的类是可变的,就必须采取必要的措施来保护该成员变量所引用的对象不会被修改,这样才能创建真正的不可变类
final修饰符(6)-final类的更多相关文章
- final修饰符(5)-final方法
final修饰的类的方法不能被重写,例如如果父类不希望子类重写某个方法,则可以使用final修饰符修饰该方法 在java的Object类里面有一个final方法:getClass(),因为Java不希 ...
- Java中的(构造方法、方法重载、final修饰符使用及继承和抽象)
构造方法: 构造方法的名称和类名相同,没有返回类型,参数列表(类型.个数)不同 方法重载:成员方法和构造方法都可以进行重载 方法名相同但是参数列表(类型,个数)不同,成为方法的重载. 继承:直支持单继 ...
- 类成员(static)和final修饰符
在Java类里只能包含成员变量.方法.构造器.初始化块.内部类(包括接口.枚举)5种成员,类成员是用static来修饰的,其属于整个类. 当使用实例来访问类成员时,实际上依然是委托给该类来访问类成员, ...
- 构造方法为private与类修饰符为final
构造方法为private的:在这个类外1:不能继承这个类2:不能用new来产生这个类的实例 在这个类内:1:可以继承这个类2:可以用new来产生这个类的实例 类修饰符为final的:在这个类外1:不能 ...
- 0025 Java学习笔记-面向对象-final修饰符、不可变类
final关键字可以用于何处 修饰类:该类不可被继承 修饰变量:该变量一经初始化就不能被重新赋值,即使该值跟初始化的值相同或者指向同一个对象,也不可以 类变量: 实例变量: 形参: 注意可以修饰形参 ...
- Java final 修饰符知识点总结
final从字面上理解含义为“最后的,最终的”.在Java中也同样表示出此种含义. final可以用来修饰变量(包括类属性.对象属性.局部变量和形参).方法(包括类方法和对象方法)和类. 1. fin ...
- Java中的final修饰符
1.什么时候可以选择final修饰符 如果想让一个类不被其他类继承,不允许在有子类,这时候就要考虑用到final来修饰. 2.用final修饰的类 首先大家要明白,用final修饰的类是不能被继承的, ...
- java修饰符public final static abstract transient
JAVA 修饰符public final static abstract transient 关键字: public final static abstract ... 1.public prot ...
- private static final 修饰符
java修饰符分类修饰符字段修饰符方法修饰符根据功能同主要分下几种 1.权限访问修饰符 public,protected,default,private,四种级别修饰符都用来修饰类.方法和字段 包外 ...
随机推荐
- 08.ElementUI 2.X 源码学习:源码剖析之工程化(三)
0x.00 前言 项目工程化系列文章链接如下,推荐按照顺序阅读文章 . 1️⃣ 源码剖析之工程化(一):项目概览.package.json.npm script 2️⃣ 源码剖析之工程化(二):项目构 ...
- CPU性能PK
CPU性能PK AMD vs Intel 2020: Who Makes the Best CPUs? 英文原文链接:https://www.tomshardware.com/features/amd ...
- Java SSM框架理论知识
一.Spring理论知识 1.Spring 在ssm中起什么作用? Spring:轻量级框架 作用:Bean工厂,用来管理Bean的生命周期和框架集成. 两大核心:1.IOC/DI(控制反转/依赖注入 ...
- 『动善时』JMeter基础 — 41、使用JMeter连接数据库(MySQL)
目录 1.为什么要使用JMeter连接数据库 2.JMeter连接数据库的前提 3.JDBC连接配置组件界面介绍 4.JMeter连接数据库演示 (1)测试计划内包含的元件 (2)测试计划中添加链接数 ...
- Java Spring boot 多商户入驻 外卖|跑腿|代驾 Uniapp版本
技术说明: 源码下载:https://www.yuanmahy.com/8357.html 开发环境:jdk1.8,mysql5.7,node 9.4,redis6.2,npm6.9 开发工具:前端使 ...
- 【NX二次开发】获取体是实体还是片体UF_MODL_ask_body_type()
判断体是实体还是片体:UF_MODL_ask_body_type() //输出 Body type: //UF_MODL_SOLID_BODY 5601 //UF_MODL_SHEET_BODY 56 ...
- csp-s模拟测试57(10.2)「天空龙」·「巨神兵」·「太阳神」
题目是古埃及神话??? A. 天空龙 傻逼模拟,看来没有滑天下之大稽QAQ,也没有打错快读(大雾...) B. 巨神兵 难度爆增,一脸懵比..... 60分状压: 因为是求有向图,关于有向图好像拓扑用 ...
- 【题解】Luogu P3052 【USACO12】摩天大楼里的奶牛Cows in a Skyscraper
迭代加深搜索基础 题目描述 A little known fact about Bessie and friends is that they love stair climbing races. A ...
- 数位dp从会打模板到不会打模板
打了几个数位$dp$,发现自己除了会打模板之外没有任何长进,遇到非模板题依然什么都不会 那么接下来这篇文章将介绍如何打模板(滑稽) 假设我们要处理$l----r$ 采用记忆化搜索的方式,枚举$< ...
- Unreal如何进行材质优化?
Hello,大家好,今天给大家带来实用的材质优化,我是木偶心没.优化在每个游戏项目里面都会涉及到,是一种为了达成相同目标,寻求并采用消耗更少资源的办法.一般会在CPU,GPU,网络和内存方便进行优化. ...