-
1.12. static的一些使用场景
五个应用场景
- 修饰成员变量
- 修饰成员方法
- 静态代码块
- 修饰内部类(只能修饰内部类,也就是静态内部类)
- 静态导包(只能使用静态方法和变量,不能用非静态的)
修饰成员变量
被static修饰的成员变量叫静态变量,静态变量不属于某个对象,而是属于当前类
(每次在不同地方调用的静态变量是同一个)
访问方式
- 类名.静态变量
- Math.PI
- 对象. 静态变量(不推荐)
- math m = new Math();
- m.PI;
修饰成员方法
被static修饰的成员方法叫静态方法,静态方法不属于某个对象,而是属于当前类
(每次在不同地方调用的静态方法是同一个)
- 类名.静态方法
- Math.max(1,3)
- 对象. 静态方法(不推荐)
- math m = new Math();
- m.max(1,3);
静态代码块
三种:静态代码块,构造代码块,普通代码块
public class StaticTest { // 静态代码块 static { } // 构造代码块 { } public void hello() { // 普通代码块 { } } }
- 静态代码块只会在类加载时执行,且只会执行一次。
- 静态代码块不能访问非静态变量和非静态方法。
- 静态代码块不能定义在任何方法内,包括静态方法。
- 在静态代码块中不能使用 this 和 super 两个关键字。
执行顺序:
静态代码块 --> 构造代码块 --> 构造器
在继承关系中三者执行顺序如下:
父类静态代码块 --> 子类静态代码块 --> 父类构造代码块 --> 父类构造器 --> 子类构造代码块 --> 子类构造器
注意:静态代码块只在类加载时执行一次,但构造代码块每创建一个实例对象都会执行一次。
修饰内部类
普通内部类编译完成后会保存一个引用
静态内部类则没有引用,所以创建不需要依赖外围类的创建,且不能使用外围非static方法和变量
静态导包(感觉很少用)
格式:
import static
导入之后可以不用类名调用静态资源,直接调用类中静态方法import static java.lang.Math.*; public class Demo3 { public static void main(String[] args) { // 该方法调用未使用Math.max int max = max(6, 9); System.out.println(max); } }
1.13. String123怎么转换为数字123?
String str = "String123"; String numStr = str.replaceAll("\\D", ""); // 去掉非数字字符 int num = Integer.parseInt(numStr); // 转换为整数 System.out.println(num); // 输出:123
1.14. String a = null 和String a = “”的区别
String a;
- 只是在栈中声明了一个a的内存地址,并没有给它赋初值,也就是在没有在堆内存中申请内存地址,更没有在堆内存指向引用地址;
String a = null;
- 在栈中声明了一个a的内存地址,在堆中也申请了一个内存地址,但是堆中的地址不指向任何栈里的引用地址
String a = “”;
- 栈里申明一个string类型的 a内存地址,堆内存里申请了地址,堆内存中的地址指向引用该字符串的栈内存中的a引用地址
1.15. 为什么String不可变
-
String 底层是由final修饰的 char[] 的数组
-
String的赋值是创建一个新的对象
1.16. 判断两个String对象相等应该怎么写?
==
比较的是两个字符串引用的地址equals()
用于比较两个对象的内容是否相等所以用equals
1.17. 判断两个Double类型的数相等应该怎么写?
单精度浮点数0.1表示成二进制 Integer.toBinaryString(Float.floatToIntBits(0.1f)) 结果是:111101110011001100110011001101 双精度的浮点数0.1的二进制 Long.toBinaryString(Double.doubleToLongBits(0.1d)) 结果是:11111110111001100110011001100110011001100110011001100110011010 float转换后的double的值已经和直接赋值的double的值比较 Long.toBinaryString(Double.doubleToLongBits(0.1f)) 结果是:11111110111001100110011001100110100000000000000000000000000000
所以不能直接使用
equals
和compareTo
比较方法
-
转换成字符串
-
使用sun提供的Double.doubleToLongBits()方法
-
误差内比较
-
BigDecimal类型
-
double a = 0.001; double b = 0.0011; BigDecimal data1 = new BigDecimal(a); BigDecimal data2 = new BigDecimal(b); data1.compareTo(data2) 非整型数,运算由于精度问题,可能会有误差,建议使用BigDecimal类型!
-
1.18. Java中Stringbuilder与Stringbuffer区别及应用场景
字符区别:
String
不可变字符串,存在常量池StringBuilder
可变字符序列、效率高、线程不安全,存在堆区StringBuffer
可变字符串、效率低、线程安全,存在堆区
应用场景:
当对字符串修改
频繁
的时候,需要使用StringBuffer
和StringBuilder
类(不会产生行动未使用对象)1.19. 判断输出结果
Integer x = new Integer(123); Integer y = new Integer(123); System.out.println(x == y); 输出的结果,为什么? false ==比较的是两个不同的地址引用,这是两个对象
Integer z = Integer.valueOf(123); Integer k = Integer.valueOf(123); System.out.println(z == k); 输出的结果,为什么? true 使用Integer.valueOf方法创建对象时,如果数值在-128~127之间 则会从内部的缓存区中返回已经存在的对象,所以这两个对象指向的是同一个地址 注:如果不在-128~127区间,则结果为false,因为不是同一个地址区域了
1.20. equals重写了什么算法
-
equals方法,要不然对于对象的比较来说,比较的就是引用地址了。
- 因为对象里面的属性太多,都不知道具体比较什么(比如说比较年龄,就重写然后比较年龄)
-
hashcode方法
- 如果不重写该方法,两个相同内容的对象地址hashcode值就不一样
- 重写了相同内容的对象hashcode值就相同了