8个基本的数据类型
-
int
- 32位
- 4个字节
- 正负20亿
- 不能存手机号
-
long
- 64位
- 8个字节
-
float
- 32位
- 4个字节
- 34.0f
-
double
- 64位
- 8个字节
-
short
- 16位
- 2个字节
-
byte
-
char
- 16位
-
boolean
final 关键字
final: Final用于修饰类、成员变量和成员方法。
final修饰的类,不能被继承(String、StringBuilder、StringBuffer、Math,不可变类),其中所有的方法都不能被重写(这里需要注意的是不能被重写,但是可以被重载,这里很多人会弄混),所以不能同时用abstract和final修饰类(abstract修饰的类是抽象类,抽象类是用于被子类继承的,和final起相反的作用);
Final修饰的方法不能被重写,但是子类可以用父类中final修饰的方法;
Final修饰的成员变量是不可变的,如果成员变量是基本数据类型,初始化之后成员变量的值不能被改变,如果成员变量是引用类型,那么它只能指向初始化时指向的那个对象,不能再指向别的对象,但是对象当中的内容是允许改变的
摘要:
-
一旦赋值不能被修改
-
修饰类
- 不能被继承
-
修饰方法
- 不能被重写,可以重载
-
重载:一个类里面,方法名形同,参数列不同,叫重载。
-
重写(覆写):子类对父类可访问方法的重新编写,方法名相同,参数列表一致,叫重写。
-
方法覆写定义:
与父类方法名称、参数类型及个数完全相同
覆写方法不能拥有比父类更为严格的访问控制权限(public>default>private)
若父类方法由private修饰,则此方法不能够方法覆写(private代表只能在本类中可见,则子类根本 不知道父类有这样一个方法,则不能覆写)
-
- 不能被重写,可以重载
-
位运算
-
1.左移运算符
左移运算符用“<<”表示,是将运算符左边的对象,向左移动运算符右边指定的位数,并且在低位补零。其实,向左移n 位,就相当于乘上2 的n 次方,例如下面的例子。
public class data17
{
public static void main(String[] args)
{
int a=2;
int b=2;
System.out.println("a 移位的结果是:"+(a<<b));
}
}
运行结果
a 移位的结果是:8
分析上面的程序段:
首先从本质上来分析,2 的二进制是00000010,它向左移动2 位,就变成了00001000,即8。如果从另一个角度来分析,它向左移动2 位,其实就是乘上2 的2 次方,结果还是8。
2.无符号右移运算符
右移运算符用符号“>>>”表示,是将运算符左边的对象向右移动运算符右边指定的位数,并且在高位补0,其实右移n 位,就相当于除上2 的n 次方。
public class data18
{
public static void main(String[] args)
{
int a=16;
int b=2;
System.out.println("a 移位的结果是:"+(a>>>b));
}
}
运行结果
a 移位的结果是:4
分析上面的程序段:从本质上来分析,16 的二进制是00010000,它向右移动2 位,就变成了00000100,即4。如果从另一个角度来分析,它向右移动2 位,其实就是除以2 的2 次方,结果还是4。
3.带符号的右移运算符
带符号的右移运算符用符号“>>”表示,是将运算符左边的运算对象,向右移动运算符右边指定的位数。如果是正数,在高位补零,如果是负数,则在高位补1,先看下面一个简单的例子。
public class data19
{
public static void main(String[] args)
{
int a=16;
int c=-16;
int b=2;
int d=2;
System.out.println("a 的移位结果:"+(a>>b));
System.out.println("c 的移位结果:"+(c>>d));
}
}
运行结果
a 的移位结果:4
c 的移位结果:-4
分析上面的程序段:
a 的值是16,转换成二进制是00010000,让它右移两位成00000100 即4。
c 的值是-16,转换成二进制是11110000,让它右移两位成11111100 即-4。
tip:-16带符号右移2位的计算详情(掌握二进制十进制(正负数)的转换)
16的二进制00010000,反码11101111,反码+1得到补码11110000,带负符号右移,所以高位补1,得11111100.此为二进制的负数,减一求反码即可。11111100减一得11111011,反码00000100,即为4,带符号,结果为-4.
-
注意 无符号右移 无论首位是0还是1 右移之后都会补0
-
以及右移 要对32取模
-
强制类型转换 下图 逆方向都要强制类型转换 而且 要加上强制类型转换的类型
-
int a=(int) 123L;
字符串
字符串如何保证不可变
- char类型的数组 用final修饰
- String 类 也是final修饰
- 希望本类的所有特性(方法)不被子类修改
- 没有提供修改字符串的方法
private final char value[];
字符串是一种不可变对象,指的是它的内容不可改变,但是引用是可以改变的,String类内部实现也是基于char[]来实现的,并且源码中String类是私有的并没有提供方法修改类内部的字符数组
形如+=这样的操作表面是修改了字符串,其实不是。
注意这里做了两次拼接,会产生两个临时的对象,程序结束后,这些临时对象就会被垃圾回收器回收。
== 和 equals 的区别是什么?
== : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。(基本数据类型 == 比较的是值,引用数据类型 == 比较的是内存地址)
equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:
情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。
情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来两个对象的内容相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。<–
String API
String str = "abcdef";
//charAt 返回第几个字符
System.out.println("第几个字符:" + str.charAt(0));
//codePointAt 返回a这个字符的码点是多少
System.out.println("码点是:" + str.codePointAt(0));
//offsetByCodePoints
System.out.println("" + str.offsetByCodePoints(0, 1));
//compareTo 返回0相同,返回正数 str在“abcde”之后,返回负数在“abcde”之前
System.out.println("字典序比较:" + str.compareTo("abcde"));
//startsWith
System.out.println("是否以“”开头:" + str.startsWith("a"));
//endsWith
System.out.println("是否以“”结尾:" + str.endsWith("f"));
//equalsIgnoreCase 忽略大小写
System.out.println("忽略大小写:" + str.equalsIgnoreCase("ABCDEF"));
//indexOf
System.out.println("a相对与位置什么地方:" + str.indexOf("a"));
System.out.println("f相对与位置什么地方:" + str.indexOf("f"));
//indexOf 97->码点 从第几个开始,默认是从第0个开始
System.out.println("a相对与位置1的什么地方:" + str.indexOf(97,1));
//lastIndexOf 注意:lastIndexOf()方法虽然是从后往前搜索,但返回的位置是从前开始数的。
System.out.println("a相对与位置1的什么地方(从后往前):" + str.lastIndexOf(97,1));
//lastIndexOf
System.out.println("a相对与位置什么地方:" + str.lastIndexOf("a"));
System.out.println("f相对与位置什么地方:" + str.lastIndexOf("f"));
//toUpperCase
System.out.println("变为大写:" + str.toUpperCase());
//toUpperCase
System.out.println("变为小写:" + "ABCDE".toLowerCase());
//substring
System.out.println("从第一个位置切割:" + str.substring(1));
//substring 3-1 = 2 不包括第三个位置 abcdef
System.out.println("从第一个位置切割到第三个位置:" + str.substring(1,3));
String str2 = " aaabbb ";
System.out.println("去除空格:" + str2.trim());
System.out.println("以逗号隔开:" + String.join(" ",str,"a","b","c"));
List<String> list = new ArrayList<String>();
list.add("s1");
list.add("s3");
list.add("s5");
list.add("s7");
System.out.println(String.join(",", list));
运行结果:
Java 的设计者认为共享带来的高效率远远胜过于提取、 拼接字符串所带来的低效率
1、StringBuilder 与 StringBuffer
StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
2、区别
StringBuffer 和 StringBuilder 区别在于,StringBuffer 是线程安全,StringBuilder 反之。
StringBuilder
StringBuffer
StringBuffer是线程安全的高效字符串操作类,在StringBuilder上加了锁机制
构造方法:
StringBuffer();
StringBuffer(String str)
StringBuffer(CharSequence seq)
StringBuffer(int capacity)
实例化时,初始化大小容量为16
append方法时,会有容量大小的判断。如果append添加字符长度大于初始化容量16,则按新算法计算容量大小,如果append的字符串长度超过16,则容量为34 (34=16 * 2 + 2)
要是append的字符串长度超过16,并且大于34,则直接为字符串需要的长度。
3.2 写法二
StringBuffer sb = new StringBuffer(“java”);
StringBuffer(CharSequence seq)
与写法一区别
实例化时,初始化大小容量为 (实例化参数字符串的长度+ 16),其它逻辑与写法一相同。
.3 写法三
StringBuffer sb = new StringBuffer(20);
与写法一区别
实例化时,初始化大小容量为 (自定义大小),其它逻辑与写法一相同。