您的位置:首页 > 游戏 > 手游 > 建筑课堂首页_网站设计哪家专业_域名购买平台_湖南专业关键词优化

建筑课堂首页_网站设计哪家专业_域名购买平台_湖南专业关键词优化

2024/12/23 15:39:14 来源:https://blog.csdn.net/m0_75235246/article/details/142351007  浏览:    关键词:建筑课堂首页_网站设计哪家专业_域名购买平台_湖南专业关键词优化
建筑课堂首页_网站设计哪家专业_域名购买平台_湖南专业关键词优化

包装类:

        在学习泛型之前我们一定要认识包装类。

        在Java 中,由于基本类型不是继承自 Object ,为了在泛型代码中可以支持基本类型, Java 给每个基本类型都对应了一个包装类型。
除了int类型和char类型的包装类不是它们对应的基本类型的大写之外,其他的都是将基本类型的首字母大写!

包装类中也有对应的许多方法,例如:将字符串类型转为整型: 

我们以Integer包装类为例研究。

拆箱和装箱:

        拆箱和装箱也被称为拆包和装包:

装箱:

也就是将基本类型变成包装类的过程:

例如:

此时就对基本类型完成了装箱过程:

需要调用Integer的静态方法完成装箱:

这个静态方法是什么意思呢?

可以一起看看,源码如下:

    public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);}

首先进入源码有一个if语句,我们看看能能不能看懂。

Integer.low和Integer.high是什么意思呢?

我们同样找到low和high中,发现low是-128,high是127,也就是当我们传过来的参数如果小于-128或者大于127,这时候先调用Integer的构造函数之后就直接new一个新的Integer对象返回。

将类中的value初始化,完成整个装箱过程!!

但是如果此时我输入的值在-128和127之间会发生什么?
继续来看:

此时返回一个数组对应的值,cache是该类一开始就定义的一个Integer数组类型的成员变量:

那么这个数组中放的是什么呢?

在一开始的静态代码块中有初始化:

发现这个数组中首先只有(127+128+1 = 256)的大小,j = -128;之后将参数为-128 - 127的Integer类型的放在数组中,下标从0 - 255!!

这时候就明白了,原来这个数组中存放的就是-128到127的Integer类型的变量。

所以当我们传参如果大于127或者小于-128的时候,这时候会计算一个位置然后返回,如果是3,那么就返回3+128 = 131位置的对应的Integer对象,131位置上Integer初始化的value正好是3。

如上就是原理图!!

拆箱:

        就是将包装类变成基本类型:

例如:

    public static void main(String[] args) {Integer i = Integer.valueOf(10);int a = i.intValue();System.out.println(a);}

这就是拆箱过程,也就是调用封装对象的intValue方法。

源码如下;:

这个通俗易懂直接返回一个int类型的值。 

自动拆箱和装箱:

        名表了拆箱和装箱的原理,也知道拆线和装箱需要调用哪个方法。

        但是此时我写这样的代码,看看编译器能否通过编译!

首先没有报错,再其次打印结果如下:

此时有两个问题:

        1.Integer引用类型为什么可以直接接受一个int类型的变量?

        2.为什么我直接打印Integer引用类型变量,打印结果是一个10?

接下来一一解答该问题:

        1.编译器会为我们自动完成拆箱和装箱的过程!

        2.Integer包装类中已经重写了toString方法!! 

自动拆箱演示过程:
 

泛型:

什么是泛型:

        泛型:就是适用于许多许多类型。从代码上讲,就是对类型实现了参数0化。

语法:

class 泛型类名称 < 类型形参列表 > {
// 这里可以使用类型参数
}
class ClassName < T1 , T2 , ..., Tn > {

}

class 泛型类名称 < 类型形参列表 > extends 继承类 /* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
class ClassName < T1 , T2 , ..., Tn > extends ParentClass < T1 > {
// 可以只使用部分类型参数
}
class MyArray<T> {
public T[] array = (T[])new Object[10];//1
public T getPos(int pos) {
return this.array[pos];
}
public void setVal(int pos,T val) {
this.array[pos] = val;
}
}
public class TestDemo {
public static void main(String[] args) {
MyArray<Integer> myArray = new MyArray<>();//2
myArray.setVal(0,10);
myArray.setVal(1,12);
int ret = myArray.getPos(1);//3
System.out.println(ret);
myArray.setVal(2,"bit");//4
}
}
代码解释:
1. 类名后的 <T> 代表占位符,表示当前类是一个泛型类
了解: 【规范】类型形参一般使用一个大写字母表示,常用的名称有:
E 表示 Element
K 表示 Key
V 表示 Value
N 表示 Number
T 表示 Type
S, U, V 等等 - 第二、第三、第四个类型
2. 注释 1 处,不能 new 泛型类型的数组:
class 泛型类名称 < 类型形参列表 > extends 继承类 /* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
class ClassName < T1 , T2 , ..., Tn > extends ParentClass < T1 > {
// 可以只使用部分类型参数
}
class MyArray < T > {
public T [] array = ( T []) new Object [ 10 ]; //1
public T getPos ( int pos ) {
return this . array [ pos ];
}
public void setVal ( int pos , T val ) {
this . array [ pos ] = val ;
}
}
public class TestDemo {
public static void main ( String [] args ) {
MyArray < Integer > myArray = new MyArray <> (); //2 当编译器可以根据上下文推导出类型实参 时,可以省略类型实参的填写
myArray . setVal ( 0 , 10 );
myArray . setVal ( 1 , 12 );
int ret = myArray . getPos ( 1 ); //3
System . out . println ( ret );
myArray . setVal ( 2 , "bit" ); //4
}
}
T [] ts = new T [ 5 ]; // 是不对的
3. 注释 2 处,类型后加入 <Integer> 指定当前类型
4. 注释 3 处,不需要进行强制类型转换
5. 注释 4 处,代码编译报错,此时因为在注释 2 处指定类当前的类型,此时在注释 4 处,编译器会在存放元素的时候帮助我们进行类型检查。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com