文章目录
- 数据类型
- 八大基本数据类型
- Java中有了基本数据类型,为什么还要包装类型
- String
- 字符串类型函数
- 字符串类的length()方式是否能够得到字符串内有多少个字符?
- 不可变字符串
- String为什么要设计成不可变的?
- boolean类型占多少位?为什么?
- “”与null
- 汉字占位?字母占位?
- 数值类型转换
- 强制类型转换
- 枚举类型
———————————————————————————
数据类型
八大基本数据类型
Java中有了基本数据类型,为什么还要包装类型
-
Java是一个面向对象的语言,然而基本数据类型不具备面向对象的属性。当我们把基本数据类型包装成包装类型后,基本数据类型就具备了面向对象的属性。
-
在ArrayList 、HashMap这些容器来存放数据是,基本类型int和double是存放不进去的,因为容器都是装泛型(object类型)的,所以需要转为包装类型进行存放。
-
每一个基本类型都有对应的包装类型
二者的区别
- 包装类是对象,拥有方法和字段,对象的调用都是通过引用对象的地址;基本类型不是
- 包装类型是引用的传递;基本类型是值的传递
- 声明方式不同:
- 基本数据类型不需要new关键字;
- 包装类型需要new在堆内存中进行new来分配内存空间
- 存储位置不同:
- 基本数据类型直接将值保存在值栈中;
- 包装类型是把对象放在堆中,然后通过对象的引用来调用他们
- 初始值不同:
- int的初始值为0、boolean的初始 值为false
- 包装类型的初始值为null
- 使用方式不同:
- 基本数据类型直接赋值使用就好;
- 在集合如collection,Map时只能使用包装类型
String
字符串类型函数
1、字符串是引用类型:改变值的大小,所占空间会发生改变
2、基本类型:值可以改变,空间仍是4字节32比特
基本类型,值和地址在一块,而引用类型,值和地址不在一起,内存存储地址,值改变相当于指向了另外的地址。地址的长度固定,值的空间取决于定义/申请 的大小
(1)equals(): 判断字符串是否相等
先判断地址是否相等,地址相同的话返回true,地址不同的话,再判断值是否相同,值相同的话返回true。
String a = "123abc"; String b = "12";
System.out.println(a.equals(b));
(2)indexOf(): 目标字符或字符串在原字符串所在的位置
返回值是int类型,位置下标从0开始,如果目标字符不存在,返回-1
String a = "123abc"; int indexa = a.indexOf("3a"); System.out.println(indexa);
(3)valueOf(): 其他类型转换为字符串类型
Integer i = 1000;
String valuei = String.valueOf(i); System.out.println(valuei);
//输出字符串类型的1000
(4)charAt(): 获取下标位置的字符
String a = "123abc";
char x = a.charAt(4);
System.out.println(x);
(5).length(): 获取字符串的字符数量
String c;
String d = "";
【1】c和d不同,输出c会报错,输出d会显示没有输出;
【2】c是指null,d是指""(长度为0的字符串)
【3】如果要判断一个字符串不为空,应该if(str != null && str.length() != 0)
(6)isEmpty(): 判断字符串长度是否为0
(7)contains(): 判断原字符串当中是否包含目标字符
String a = "123abc"; System.out.println(a.contains("23"));
(8)replace(): 字符串替换
String a = "123abca"; System.out.println(a.replace("a","h")); //输出123hbch
(9)trim(): 去除字符串首位空格
用户在输入数据的时候往往在前后输入空格
(10)subString(): 截取字符串
String a = "123abca"; System.out.println(a.sunString(2));
//从第二个数据开始(不是下标为2)到结束
System.out.println(a.sunString(2,5));//截取[2,5)
(11)split(): 拆分字符串
str.split(String regex, int limit)
regex:正则表达式分隔符。
limit:分割的份数。
-------
String str = "one two three four";
String[] tokens = str.split(" ",2);
for (String s: tokens)
System.out.println(s);
//输出:
one
two three four
----------
1、如果用“.”作为分隔的话,必须的写法是“String.split("\\.")”,不能用String.split(".")。
2、如果用“|”作为分隔的话,必须的写法是“String.split("\\|")”。
(12)toCharArray(): 将字符串对象中的字符转换为一个字符数组
String a = "123abc"; System.out.println(a.toCharArray());
//输出:[1,2,3,a,b,c]
(13)toLowerCase(): 将字符串中的字母全部转换为小写,非字母不受影响
字符串名.toLowerCase()
(14)toUpperCase(): 将字符串中的字母全部转换为大写,非字母不受影响
字符串名.toUpperCase()
字符串类的length()方式是否能够得到字符串内有多少个字符?
不能,因为length()获取的是代码单元,有的字符占用两个代码单元,这也是根据编码决定的;
不可变字符串
- 不可变字符串:不可以在原地址空间修改数据,
- 字符串每次=意味着开辟新的空间,即使是拼接数据,也要重新申请空间
字符串不可变 指的是不能在原地址修改,只能重新申请空间完成修改。
String底层是一个final修饰的char类型的数组,所以数组一旦被赋值,value 的保存地址将不可变,而且String 类型并没有给我们提供操作数组元素的方法,所以String字符串的不可变是指在原来的地址上不能被改变。
String为什么要设计成不可变的?
①:便于实现字符串池
在Java中,有时候我们会大量的使用String常量,如果每一次声明一个String都创建一个String对象,那将会造成极大的空间资源的浪费。
所以Java就在堆中开辟一块存储空间也就是字符串常量池,当初始化一个String变量时,如果该字符串已经存在了,就不会去创建一个新
的字符串变量,而是会返回已 经存在了的字符串的引用。
如果字符串是可变的,某一个字符串变量改变了其值,那么其指向的变量的值也会改变,字符串常量池也就不能够实现了。
②:多线程保证写操作的安全
在并发场景下,多个线程同时读一个资源,是安全的,不会引发竞争。但对资源进行写操作时是不安全的,不可变对象不能被写,所以保证了多线程的安全。
③:某些特殊的场景下的安全问题,比如网络连接地址URL,文件路径path,反射机制所需要的String参数
如果字符串是可变的,黑客就有可能改变字符串指向对象的值,那么会引起很严重的安全问题。
④:加快字符串的处理速度
由于String是不可变的,保证了 hashcode 的唯一性,于是在创建对象时其hashcode就可以放心的缓存了,不需要重新计算。这也就是Map喜欢将String作为Key的原因,处理速度要快过其它的键对象。所以 HashMap中的键往往都使用String。
boolean类型占多少位?为什么?
boolean类型的数据,是32位,4字节;
(boolean类型的数值只有true和false,编译后用0和1表示,理论上只需要占用1bit,但是计算机最小分配单元是一个字节8bit;在java中给他分配了32bit,(为了填充缓存行,让内存行中的数据变少,读他的时候能够不被阻塞,读取更快)
“”与null
“”: 表示一个长度为0的字符串,代表声明了一个对象实例,这个对象实例的值是一个长度为0的空字符串,可以调用String类中的方法,"“只能给String类型赋值;”"占空间,底层相当于是c语言的char a[] = {‘\0’}。
null: 代表声明了一个空对象,不是一个字符串,可以赋给任何对象,不能调用任何方法,否则会出现空指针异常(NullPointerException),null常量可以给任意引用数据类型赋值;不占空间。
汉字占位?字母占位?
根据编码决定,一般情况下汉字占16位,一个字母占8位。
因为所有的编码开头都是是ASCII码,所有的字母都在ASCII编码之内,这并不代表字母都占8位,但是所有编码的编码值和ASCII编码的编码值相同。
数值类型转换
强制类型转换
枚举类型
和正常类有相同的功能
- 枚举类是限定对象个数的特殊类,
- 枚举类不能执行new操作(标志:构造方法是私有的),而且对象个数是限定好的;
- 枚举类和普通类一样有属性,有普通方法,有构造方法,构造方法必须是私有的(普通类有的功能,枚举类都有);
- 利用枚举可以实现单例模式(利用枚举是实现单例模式最简单的方式)。