首先,final的用法:在什么时候需要使用final?
1.当final修饰一个类的时候,那么该类不能被继承。final类中的所有成员方法都会被隐式地指定为final方法。
比如在java.lang包里面不能被继承的类
public final class Byte
public final class Character
public static final class Character.UnicodeBlock
public final class Class<T>
public final class Compile
public final class Double
public final class Float
public final class Integer
public final class Long
public final class Math
public final class ProcessBuilder
public final class RuntimePermission
public final class Short
public final class StackTraceElement
public final class StrictMath
public final class String
public final class StringBuffer
public final class StringBuilder
public final class System
public final class Void
另外一种阻止类的继承的方法是显示的将构造函数置为private,这样的话子类将调用不了超类的方法,也就达到了不能被继承类的作用。
那么为什么不让继承这个类呢(他怎么这么自私不让被继承2333)?
答:final,防止任何继承类改变它本来的含义(也可以说是上锁吧)当你将final用于类身上时,一个final类是无法被任何人继承的,那也就意味着此类在一个继承树中是一个叶子类,并且此类的设计已被认为很完美而不需要
进行修改或扩展。对于final类中的成员,你可以定义其为final,也可以不是final。而对于方法,由于所属类为final的关系,自然也就成了final型的。当然也可能会有安全方面的因素,使用final不进行子类化。
final对于方法中为什么要用到?
答:目的其实是给方法进行上锁,一个方法在继承期间保持不变,不能被覆盖或者改写,就可以采用这个做法。
采用final方法对于程序执行效率上面有什么优势?
答:编译器就可以把对那个方法的所有调用都置入“嵌入”调用里。只要编译器发现一个final方法调用,
就会(根据它自己的判断)忽略为执行方法调用机制而采取的常规代码插入方法(将自变量压入堆栈;跳至方法代码并执行它;跳回来;清除堆栈自变量;最后对返回值进行处理)。
相反,它会用方法主体内实际代码的一个副本来替换方法调用。这样做可避免方法调用时的系统开销
Java编译器能自动侦测这些情况,并颇为“明智”地决定是否嵌入一个final方法。然而,最好还是不要
完全相信编译器能正确地作出所有判断。通常,只有在方法的代码量非常少,或者想明确禁止方法被覆盖的时候,才应考虑将一个方法设为final。类内所有private方法都自动成为final。由于我们不能访问一个private方法,所以它绝对不会被其他方法覆盖(若强行这样做,编译器会给出错误提示)。
可为一个private方法添加final指示符,但却不能为那个方法提供任何额外的含义。
被final修饰的变量的特点?
答:被final修饰的变量其实就相当于定义了一个常量,无法被修改的变量,如果final修饰的是一个基本数据类型的变量,那么这个变量的值就定了,不能变了,而如果修饰的是一个引用变量,那么该变量存的是一个内存地址,该地址就不能变了,但是该内存地址所指向的那个对象还是可以变的
(final修饰的变量地址不能变,但是地址所指向的对象可以变)(家被固定了,但是住着谁无所谓)
给方法定义的参数是 final类型的,是不想别人在方法内部修改参数的值,如果final修饰的是一个基本类型,那么是可以的,如果修饰的是引用类型,那么便不行了,因为就如上文那个str.append 对象的内容是可以变化的!(所以方法的入参是引用类型的变量其实并不能防止别人更改ta的内容)
附:java基本的数据类型(java分为基本的数据类型和引用类型)
byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0
short:短整型,在内存中占16位,即2个字节,取值范围-32768~32717,默认值0
int:整型,用于存储整数,在内在中占32位,即4个字节,取值范围-2147483648~2147483647,默认值0
long:长整型,在内存中占64位,即8个字节-2^63~2^63-1,默认值0L
float:浮点型,在内存中占32位,即4个字节,用于存储带小数点的数字(与double的区别在于float类型有效小数点只有6~7位),默认值0
double:双精度浮点型,用于存储带有小数点的数字,在内存中占64位,即8个字节,默认值0
char:字符型,用于存储单个字符,占16位,即2个字节,取值范围0~65535,默认值为空 (char的话两个字节!!1 byte = 8 bit ;char 在java中是2个字节。java采用unicode,2个字节(16位)来表示一个字符!!)
boolean:布尔类型,占1个字节,用于判断真或假(仅有两个值,即true、false),默认值false