记一次被面试的final问题
---- 前言
今天面试被问到了,我们都知道final修饰的东西是不可变的,那么是值不可变还是其地址不可变?一脸懵逼,回来查阅一番,总结一下
--- final与数据
在日常行为下,一般数据指的都是基本数据变量或者常量。当final修饰的是一个基本的数据变量时,那么该变量的值就相当于一个常数不可变,当final修饰的是一个对象时,那么对于对象句柄,final会将句柄变成一个常数,就是此时不可变的对象的引用。
然后,final修饰的对象是不可以重新指向新的一个对象的,但是自身对象的内容可以进行改变。
举个栗子
package com.xxg;
class Value {
int i = 1;
}
public class FinalData {
// Can be compile-time constants
final int i1 = 9;
static final int I2 = 99;
// Typical public constant:
public static final int I3 = 39;
// Cannot be compile-time constants:
final int i4 = (int)(Math.random()*20);
static final int i5 = (int)(Math.random()*20);
Value v1 = new Value();
final Value v2 = new Value();
static final Value v3 = new Value();
//! final Value v4; // Pre-Java 1.1 Error:
// no initializer
// Arrays:
final int[] a = { 1, 2, 3, 4, 5, 6 };
public void print(String id) {
System.out.println(
id + ": " + "i4 = " + i4 +
", i5 = " + i5);
}
public static void main(String[] args) {
FinalData fd1 = new FinalData();
//! fd1.i1++; // Error: can't change value
fd1.v2.i++; // Object isn't constant!
fd1.v1.i++;
fd1.v1 = new Value(); // OK -- not final
for(int i = 0; i < fd1.a.length; i++)
fd1.a[i]++; // Object isn't constant!
//! fd1.v2 = new Value(); // Error: Can't
//! fd1.v3 = new Value(); // change handle
//! fd1.a = new int[3];
fd1.print("fd1");
System.out.println("Creating new FinalData");
FinalData fd2 = new FinalData();
fd1.print("fd1");
fd2.print("fd2");
}
}
结果:
fd1: i4 = 6, i5 = 11
Creating new FinalData
fd1: i4 = 6, i5 = 11
fd2: i4 = 11, i5 = 11
分析:
i1和i2都是具备final属性的基本数据类型变量,并且在编译期都是具备有编译值的,而i3其实也差不多,只是多了public的访问修饰可以允许外边访问以及static强调只有一个
i4和i5则证明了不是所有被final修饰的在编译期就能够确定值为多少,这两个都是在运行时调用随机函数生成数才能确认值。同时也看到了,由于i5是static修饰的,因为它的值并不会由于fd1和fd2对象的创建而发生改变。
举个栗子
public static void main(String[] args)
{
final FinalString fs = new FinalString("1");
final FinalString fss = new FinalString("333");
fs = fss;
}
public static void main(String[] args)
{
final String[] strs0 = {"123","234"};
final String[] strs1 = {"345","456"};
strs1 = strs0;
strs1[1] = "333";
}
分析:
这两个程序的运行会报错“The final local variable fs cannot be assigned”,被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的,如果将第二程序的 strs1=str0 去掉,那么程序就可以正常运行
--- final与方法
会使用final修饰方法,一方面的情况时为了确保该方法不会被修改或者由于继承类改变它的原本含义,另外一种情况时考虑到代码的运行效率问题,假如已经确定了某个方法是不会在变化了,那么可以通过final修饰,将其直接加载进入方法区,而可以忽略每次使用完方法和使用完后,堆内的压栈等一系列操作,可以减少系统的开销。
类内所有private方法都自动成为final。由于我们不能访问一个private方法,所以它绝对不会被其他方法覆盖(若强行这样做,编译器会给出错误提示)。可为一个private方法添加final指示符,但却不能为那个方法提供任何额外的含义。
---fianl与类
如果说整个类都是final(在它的定义前冠以final关键字),就表明自己不希望从这个类继承,或者不允许其他任何人采取这种操作。换言之,出于这样或那样的原因,我们的类肯定不需要进行任何改变;或者出于安全方面的理由,我们不希望进行子类化(子类处理)。
将类定义成final后,结果只是禁止进行继承——没有更多的限制。然而,由于它禁止了继承,所以一个final类中的所有方法都默认为final。因为此时再也无法覆盖它们。所以与我们将一个方法明确声明为final一样,编译器此时有相同的效率
选择。可为final类内的一个方法添加final指示符,但这样做没有任何意义。
参考文献:《thinging in java》
记一次被面试的final问题的更多相关文章
- 记一次HashMap面试
记一次HashMap面试 从网上已经身边同事朋友的面试情况来看,面试HashMap几乎是必问的,网上也很多类似的文章,但是真面起来,发现还是有很多点可以深抠的.本篇就结合一次面试经历说一下之前没有注意 ...
- 对于大学4年的反思(续),记我的ThoughtWorks面试
之前我写了一篇对于大学四年的反思,时隔一个月,为什么我这么快就要来写这篇续章呢?主要有两个原因,第一是感谢静子姐姐,记得知乎上有个回答里面说过人生需要有贵人的帮助,遇到贵人是一件很幸运的事情.我想,静 ...
- 记一次ThreadPoolExecutor面试
ThreadPoolExecutor点滴 线程池应该也是面试绕不开的一个点,平时大家也没少用,但其实也有一些小Tips还是值得记录一下. Constructor public ThreadPoolEx ...
- 记一次Java面试问题点总结
引言 昨日接了一个阿里外包的电话面试,问了一些技术问题感觉到自己是真的菜,接触Java开发已经也有一段时间,技术方面说来惭愧,一直以来只是局限于框架工具的用法,也没有进行了解其实现的原理,更重要的是一 ...
- Java Web架构知识整理——记一次阿里面试经历
惭愧,从一次电面说起.我个人在某国企做一名软件设计师,国企大家都懂的,待遇一般而且没啥意思,做的方向基本都是操作系统.驱动和工具软件的开发,语言基本都是C/C++.最近也想跳槽,刚好有幸得到了一次阿里 ...
- 记一次 Google 面试经历
本文由码农网 – 小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 这是我上周去面试的地方.很顺利,我觉得——至少我认为我已经尽我所能,并且无论发生什么事情对我都是有帮助的. 由于 ...
- 记一次C#面试
最近参加了工作后的第一次面试,虽然最终没谈成,但是收获还是不少,不管是技术还是面试经验还是得多多积累呀. 这一次面试与在学校时候参加过的面试区别还是挺大的.校园招聘的面试问的问题似乎都比较具体,直接针 ...
- 记一次前端面试~终于拿到理想中的offer!
2019年已经过去一半,终于拿到一直想去的公司offer,也算是实现了今年的一个小目标. 由于这家公司是我从去年到现在最想去的公司,本次换工作一直没有投,希望先积累下面试经验再投. 没有想到居然先在b ...
- <面试题分享> 记两次58面试
说明 来北京找工作,有个猎头看我的简历不错,帮我投了两个58同城的面试,投的都比较高,题也注重原理,较难,这里分享出来,给有需要的人和自己提个醒,保持空杯 面试题内容 2019.05.07 北京58企 ...
随机推荐
- Unity3d 应用系统分析
- ubuntu下7z文件的解压方法(转载)
转自:http://qtlinux.blog.51cto.com/3052744/569406 打开终端,键入以下命令: apt-get install p7zip-full 控制台会打出以下信息: ...
- 洛谷 P4012 深海机器人问题 【最大费用最大流】
和火星那个有点像,但是这个价值直接在路径上,不用拆点,对于每条价值为w的边(i,j),连接(i,j,1,w)(i,j,inf,0),表示价值只能取一次,然后连接源点和所有出发点(s,i,k,0),所有 ...
- CCF2016.4 - A题
思路:枚举每个点,看看它是否同时小于/大于前一个点和后一个点 import java.util.Scanner; public class Main { public static void main ...
- 【练习】Java实现的杨辉三角形控制台输出
import java.util.Scanner; /** * YangHui_tst01 * @author HmLy * @version 000 * - - - - - - - * 练习代码.( ...
- 【原创】CentOS 6.5 中安装 Mysql 5.6,并远程连接Mysql
ι 版权声明:本文为博主原创文章,未经博主允许不得转载. 1.在安装CentOS时,若选择的是Basic Server(可支持J2EE开发),则新安装好的CentOS系统中默认是已经安装了一个mysq ...
- php 打包下载
<?php class zipfile { var $datasec = array (); var $ctrl_dir = array (); var $eof_ctrl_dir = &quo ...
- CF1119F Niyaz and Small Degrees
题意 给你\(n\)个点的树,边有边权 问使得所有的点度数都小于等于\(x\)的最小删边的代价 \([x \in 0...n-1]\) 题解 首先对于每个\(x\) 可以有一个\(O(nlogn)\) ...
- 51Nod 1315 合法整数集
1315 合法整数集 题目来源: TopCoder 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 一个整数集合S是合法的,指S的任意子集subS有Fu ...
- 题解报告:hdu 1212 Big Number(大数取模+同余定理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1212 Problem Description As we know, Big Number is al ...