JAVASE面试题(二)

本文详细解释了Java中static关键字的应用场景,包括修饰成员变量、成员方法、静态代码块、静态内部类和静态导包,以及String的处理技巧如转换为数字、不可变性、equals和hashCode的重写。还讨论了StringBuilder和StringBuffer的区别及其使用场景,以及Integer对象的equals方法行为差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 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的内存地址,并没有给它赋初值,也就是在没有在堆内存中申请内存地址,更没有在堆内存指向引用地址;

    202401111624952

    String a = null;

    • 在栈中声明了一个a的内存地址,在堆中也申请了一个内存地址,但是堆中的地址不指向任何栈里的引用地址

    202401111626374

    String a = “”;

    • 栈里申明一个string类型的 a内存地址,堆内存里申请了地址,堆内存中的地址指向引用该字符串的栈内存中的a引用地址

    202401111628638

    1.15. 为什么String不可变
    • String 底层是由final修饰的 char[] 的数组

    • String的赋值是创建一个新的对象

    image-20240111163434634

    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
    

    所以不能直接使用equalscompareTo

    比较方法

    • 转换成字符串

    • 使用sun提供的Double.doubleToLongBits()方法

    • 误差内比较

      • image-20240111165643202
    • 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可变字符串、效率低、线程安全,存在堆区

    应用场景:

    当对字符串修改频繁的时候,需要使用 StringBufferStringBuilder 类(不会产生行动未使用对象)

    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值就相同了
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值