Java final与泛型详细解析
作者:芝士汉堡猫
一、final关键字
为什么会有final关键字?答:确保它们不会在子类中改变语义。
特点:
(1)修饰常量:必须赋值的操作,且只能被赋值一次,之后不可修改;
a.当final修饰属性时(必须手动赋值,系统不会自动赋值):
·所有对象共同用一个常量时--可显示初始化赋值,可代码块中初始化;
·当每个对象使用不同值时->可以构造器中初始化。
b.当final修饰局部变量时:
·由final修饰变量只可复制一次,所以final修饰形参后,调用方法给常量实参后,在方法体内不可重新赋值;
c.当final修饰引用类型变量时:
·不可以赋予其新对象(新地址),但是对象中的内部信息可以更改。
(2)修饰方法:final修饰的方法不能被重写;
(3)修饰类:final修饰的类不能被继承,String就是final修饰的类。
(4)static final修饰属性->全局常量:
·声明在方法区中,可以节省空间,无需使创建一次对象新建一次
二、泛型<>——泛指一切类型
相关知识:栈是一种满足数据先进后出的数据结构。
示例代码:
//入栈操作↓
void push(int value){
top++;
arr[top]=value;
}
//出栈操作↓
void pop(){
println(arr[top]);
top--;
}关于链表的删除:计算机中没有真正意义上的删除,只需原来指向某一对象对应地址的指针跳过该对象,此对象不被使用之后就会被回收,完成链表的“删除”。
public class Stack<哈基米>{
private 哈基米 arr[];
private int top;
public Stack(int size){
arr=(哈基米[])new Object[size];//强转换
top=-1;
}
public void push(哈基米 value){
if(top==arr.length-1){
System.out.println("栈已满")
return;
}
arr[++top]=value;
}
public void pop(){
if(top==-1){
System.out.println("栈已空");
return;
}
}
System.out.println(arr[top--]);
}概念:泛型就是把“类型”当成“参数”来传,一份代码能适用多种类型。
public static void main(String[] args){
//整形
Stack<Integer> stack=new Stack<>(size:10);
stack.push(value:1);
stack.push(value:2);
stack.push(value:3);
stack.push(value:4);
stack.pop();
stack.pop();
//字符串
Stack<String>stack1=new Stack<>(size:10);
stack1.push(value:"张三");
stack1.push(value:"李四");
stack1.push(value:"王五");
stack1.pop();
stack1.pop();
//浮点型
Stack<Double> stack2=new Stack<>(size:10);
stack2.push(value:1.1);
stack2.push(value:1.1);
stack2.pop();
}
}
//输出为 4
3
2
王五
李四
2.2三、包装类
Java说万物皆对象,为什么有包装类?
答:基本数据类型不能有对象属性,基本数据类型不能方法的调用。
基本数据类型对应的包装类:
| 基本数据类型 | int | double | boolean | char | long | float | short |
| 包装类 | Integer | Double | Boolean | Character | Long | Float | Short |
面试题:128陷阱
public static Integer valueOf(int i){
if(i>=IntegerCache.low&&i<=IntegerCache.high)
return IntegerCache.cache[i+(-IntegerCache.low)];
return new Integer(i);
}Integer i=127; Integer j=127; System.out.println(i==j);//true Integer k=128; Integer l=128; System.out.println(k==l);//false
包装类的自动拆装箱:因为有自动拆装箱的存在,所以包装定义的数据和基本数据类型可以相互转换。

i、j、k、l在内存图中的具体表现是如何的呢?
堆内存中有Cache数组(-128~127),首先main方法入栈,i入参127在-128~127之间,则返回了127的地址值,同理,j入参127在-128~127之间,则返回了127的地址值,它们指向同一个地址,所以返回true。而k和l呢?k入参了128,并不在-128~127之间,所以会重新创建了新对象,返回新的地址,l入参了128,并不在-128~127之间,所以会重新创建了新对象,返回新的地址,但是它们创建的新地址并不相同,所以返回false。
总结:我们使用Integer定义的数据会自动进行装箱,自动装箱调用valueOf()方法,该方法会判断我们入参是否在-128~127之间,如果爱这之间,则会返回一个已存在的对象的地址(该对象在Cache数组中,Cache数组是一个从-128~127的数组),则不会创建新对象,反之则重新创建对象。
自动装箱:基本数据类型->包装类
自动拆箱:包装类->基本数据类型
基本数据类型和引用数据类型用==做输出的时候会自动拆装箱,例如Integer型和int型做==输出会自动拆箱到int型,两个数比较数值,相同则返回true,反之则返回false。但是两个相同数据类型的则不会进行自动拆装箱,例如Integer和Integer进行==输出。
到此这篇关于Java final与泛型详细解析的文章就介绍到这了,更多相关Java final与泛型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
