数据类型
一、基本数据类型
byte、short、int、long,boolean、char、float、double
1 2 4 8 1bit 2 4 8
- byte:8位有符号整数类型,取值范围-128到127,8bit=1字节
- short:16位有符号整数类型,取值范围-32768到32767
- int:32位的有符号整数类型,取值范围为-2,147,483,648到2,147,483,647,可以表示大约20亿个不同的整数。
- long:64位的有符号整数类型
- boolean:1位表示,只取值true或false
- 对应的包装类为:Byte、Short、Integer、Long、Boolean、Character、Float、Double
二、引用数据类型
类、接口、数组:如File、String、List、int[]
2.1基本数据类型 vs 引用数据类型:
基本类型
|
引用类型
|
|
内存位置
|
栈中
|
在堆中进行分配,堆的读写速度远不及栈
|
指向
|
变量名指向具体的数值
|
变量名指向存数据对象的内存地址
|
内存分配
|
声明时就分配空间。
使用:声明—赋值
|
声明时只给变量分配了引用空间而没有分配数据空间,还需要初始化
使用:声明—初始化—赋值
|
赋值
|
基本类型之间的赋值是创建新的拷贝
|
对象之间的赋值只是传递引用
|
==
|
比较的是值
|
比较两个引用是否相同,需要自己实现equals()方法
|
回收
|
基本类型变量创建和销毁很快
|
类对象需要JVM去销毁
|
2.2 值传递和引用传递
在java中,如果赋值参数是普通类型,那就是值传递,如果是对象,那就是引用传递。
注意:可以这么理解,但是从根本上来讲是不准确的,因为Java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用。
// 引用传递,templates1和templates2所操作的对象是同一个 List<RouteFactorTemplate> templates1 = routeFactorConfig.getRouteFactorTemplates(); List<RouteFactorTemplate> templates2 = routeFactorConfig.getRouteFactorTemplates(); // 引用传递,但是templates1和templates2都是new的新对象,所以他们操作的是不同对象 List<RouteFactorTemplate> templates1 = new ArrayList<>(); List<RouteFactorTemplate> templates2 = new ArrayList<>(); templates1.addAll(routeFactorConfig.getRouteFactorTemplates()); templates2.addAll(routeFactorConfig.getRouteFactorTemplates());
三、常用类/接口
3.1 Collection集合
list、set、map
3.2 String字符串
3.3 常用类
File、Date
四、byte[]——字节数组
4.1 使用
-
音频、文件类的大文件可使用byte[]来存储,以提高存取效率。
-
初始化:new byte[10],[ ]中的数值表示申请的内存空间大小。空数组使用new byte[0]
-
使用扩容:尽量避免频繁扩容。字节数组扩容,会new一个新的字节数组,并复制过去。是在内存中进行扩容,效率低;list进行add,list中存的是变量地址,位数较少,所以扩容次数少
-
赋值:字节数组赋值到新字节数组的指定位置,使用System.arraycopy()。
-
使用:可使用ByteArrayOutputStream
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byteArrayOutputStream.write(byteArray); byteArrayOutputStream.toByteArray()
4.2 空字节数组
new byte[0]
扩展:new char[0]空字符数组
4.3 类型转换
- object --> byte[]
private byte[] objectToByteAry(Object object, String type, String encoder) { if(Objects.isNull(object)){ return ArrayUtils.EMPTY_BYTE_ARRAY; } byte[] result = null; if (TypeEnum.byteAry.name().equals(type)) { result = (byte[]) object; } else if (TypeEnum.json.name().equals(type)) { result = JsonUtils.toJson(object).getBytes(StandardCharsets.UTF_8); } else if (TypeEnum.bigint.name().equals(type)) { result = ByteBuffer.allocate(Long.BYTES).putLong((long) object).array(); } else if (TypeEnum.string.name().equals(type)) { result = String.valueOf(object).getBytes(StandardCharsets.UTF_8); if (EncoderEnum.base64.name().equals(encoder)) { result = Base64.getDecoder().decode((String) object); } } else if (TypeEnum.integer.name().equals(type)) { result = ByteBuffer.allocate(Integer.BYTES).putInt((int) object).array(); } else if (TypeEnum.decimal.name().equals(type)) { result = ByteBuffer.allocate(Double.BYTES).putDouble((double) object).array(); } else if (TypeEnum.bool.name().equals(type)) { int booleanValue = (boolean) object ? AppConstants.ZERO : AppConstants.ONE; result = ByteBuffer.allocate(BOOLEAN_BYTES).putInt(booleanValue).array(); } else { throw new UnsupportedOperationException("Unsupported type:" + type); } return result; }
- byte[] --> object
private Object byteAryToObject(byte[] bytes, String type, String encoder) { Object result = null; if (TypeEnum.byteAry.name().equals(type)) { result = bytes; } else if (TypeEnum.json.name().equals(type)) { String json = new String(bytes, StandardCharsets.UTF_8); result = JsonUtils.fromJson(json, Map.class); } else if (TypeEnum.bigint.name().equals(type)) { ByteBuffer buffer = ByteBuffer.wrap(bytes); result = buffer.getLong(); } else if (TypeEnum.string.name().equals(type)) { if (!EncoderEnum.base64.name().equals(encoder)) { result = new String(bytes, StandardCharsets.UTF_8); }else{ result = bytes; } }else if(TypeEnum.integer.name().equals(type)){ result = byteArrayToInt(bytes); }else if(TypeEnum.decimal.name().equals(type)){ ByteBuffer buffer = ByteBuffer.wrap(bytes); result = buffer.getDouble(); } else if (TypeEnum.bool.name().equals(type)) { ByteBuffer buffer = ByteBuffer.wrap(bytes); int value = buffer.getInt(); result = (value != AppConstants.ZERO); } else { throw new UnsupportedOperationException("Unsupported type:" + type); } return result; }
五、byte和char
byte是字节:值为整数(97),是比short范围更小的类型
char是字符:值为字符('a'),可以组成字符串
5.1 字节和字符
字节:存储的基本单位,计算机中的概念。
-
1字节=8bit
-
汉字的字节数:取决于编码类型
-
GB2312:一个汉字通常占用2个字节。
-
GBK:一个汉字占用2个字节。
-
UTF-8:一个汉字占用3个字节。
-
UTF-16:一个汉字占用2或4个字节,大多数汉字使用2个字节,但对于一些不常用的汉字或者辅助平面上的字符,会使用4个字节。
-
字符:书写和表达的基本单位,日常概念。
-
1字符可以是字母、数字、标点符号、空格、控制符号,以及其他语言的文字等。
-
汉字的字符数:正常来讲不管采用哪种编码方案,一个汉字都是一个字符。
5.2 字节数组和字符数组
byte[]是字节数组:示例:byte[] a ={97, 35, 21 }
char[]是字符数组:示例:char[] helloArray = { 'r', 'u', 'n', 'o', 'o', 'b'};
六、long和int
数字,后面加上L就按照long类型来处理;如果不加就按照int型来处理6.1 正确写法
-
long len = 12345678901211L;
-
在java中定义:long len = 12345678901211 结果报错:error: integer number too large: 12345678901211
参考资料:https://blog.csdn.net/u010164190/article/details/72638832
6.2 long类型大小
-
long 数据类型是64 位、有符号的以二进制补码表示的整数;
-
最小值是-9,223,372,036,854,775,808(-2^63);
-
最大值是9,223,372,036,854,775,807(2^63 -1)(19位);
6.3 long返回给前端:转为String类型
-
超过2的53次方(9007199254740992)(16位)的数值转化为JS的Number时,有些数值会有精度损失。
-
2的53次方约等于72057T
-
-
转换方式
String.valueOf()
6.4 int转Long
https://geek-docs.com/java/java-examples/int-to-long.html
七、包装类型
例如int 和 Integer
1、Integer值为null时,小心NPE
Integer转为int时,会使用.intValue方法,如果值为null,就会有空指针异常
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话