java基础面试题1

什么是 Java 内部类?它有什么作用?

Java 内部类是一种定义在另一个类中的类,它与外部类(即包含内部类的类)具有紧密的联系。内部类可以访问外部类的成员变量和方法,包括私有的成员。Java 提供了多种类型的内部类,包括:

  1. 成员内部类:定义在外部类的成员位置上,可以访问外部类的所有成员,包括私有成员。
  2. 局部内部类:定义在一个方法内部的类,作用域仅限于该方法。
  3. 匿名内部类:没有名字的内部类,通常用于实现接口或继承抽象类。
  4. 静态内部类:定义在外部类的成员位置上,使用 static 关键字。它不依赖于外部类的实例,因此不能访问外部类的非静态成员。

内部类的作用包括:

  • 封装性:内部类可以隐藏在外部类中,只对需要它的代码可见。
  • 访问控制:内部类可以访问外部类的私有成员,这使得内部类可以更好地封装和实现功能。
  • 代码组织:内部类可以帮助组织和管理大型项目的代码结构。
  • 多态性:匿名内部类常用于实现多态性,通过继承或实现接口来定义具体的实现。
  • 实现特定功能:内部类可以用于实现与外部类相关的特定功能,例如事件监听器或回调机制。

使用内部类的一个典型例子是创建线程安全的单例模式,其中内部类可以访问外部类的私有构造函数来控制实例的创建。

下面是一个简单的成员内部类的示例:

java 复制代码
public class OuterClass {
    private int outerField = 9;

    // 外部类的成员方法
    public void outerMethod() {
        System.out.println("Outer method is called");
    }

    // 成员内部类
    class InnerClass {
        public void display() {
            // 直接访问外部类的成员
            System.out.println("Outer field = " + outerField);
            outerMethod();
        }
    }
}

// 使用外部类和内部类
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.new InnerClass();
inner.display();

在这个示例中,InnerClassOuterClass 的一个成员内部类,它可以访问 OuterClass 的私有字段 outerField 和公共方法 outerMethod

Java 中 String、StringBuffer 和 StringBuilder 的区别是什么?

Java 中的 StringStringBufferStringBuilder 是三种不同的类,它们在处理字符串时有不同的特性和用途:

  1. String

    • String 类型是 Java 中的不可变对象(immutable)。这意味着一旦创建了一个 String 对象,你就不能改变这个字符串中的任何字符。
    • 每次对 String 对象进行修改操作时,实际上都会创建一个新的 String 对象。
    • String 对象通常用于不需要修改的文本数据。
  2. StringBuffer

    • StringBuffer 类似于 String,但它是可变的(mutable),这意味着你可以在原有对象上进行修改,如添加或删除字符。
    • 它是线程安全的,即多个线程可以同时访问一个 StringBuffer 对象,而不会影响程序的正确性。这通过在方法上使用 synchronized 关键字来实现。
    • 由于线程安全的特性,StringBuffer 在多线程环境中更受欢迎,但可能会因为同步机制而有一些性能开销。
  3. StringBuilder

    • StringBuilderStringBuffer 类似,也是可变的,可以在原有对象上进行修改。
    • StringBuffer 不同的是,StringBuilder 不是线程安全的。这意味着如果多个线程访问同一个 StringBuilder 对象,程序的行为将是不确定的。
    • 由于没有同步机制的开销,StringBuilder 通常在单线程环境中提供更好的性能。

性能考虑

  • 对于单线程环境,如果你需要频繁修改字符串,使用 StringBuilder 通常是更好的选择,因为它没有线程安全的开销。
  • 对于多线程环境,如果多个线程需要访问同一个字符串缓冲区,使用 StringBuffer 更合适,因为它提供了线程安全。

不变性

  • String 的不变性意味着它的 hashCode 值在创建后不会改变,这使得它非常适合作为键在 HashMap 中使用。
  • StringBufferStringBuilder 的内容可以改变,所以它们不适合作为 HashMap 的键。

示例

java 复制代码
String str = "Hello";
str += " World"; // 实际上创建了一个新的String对象

StringBuffer sb = new StringBuffer("Hello");
sb.append(" World"); // 在原有对象上修改

StringBuilder sbd = new StringBuilder("Hello");
sbd.append(" World"); // 在原有对象上修改

在 Java 11 中,String 类增加了一些新的不可变工厂方法,如 isBlank(),这些方法提供了更多便利性,进一步减少了对 StringBufferStringBuilder 的需求。

Java 的反射机制?如何应用反射?

Java 的反射机制是一种在运行时(Runtime)检查或修改程序行为的能力。它允许程序在运行时动态地获取类的基本信息(如类名、方法、字段等),以及创建和操作对象。

反射的主要应用包括

  1. 动态创建对象:可以在运行时创建任何类的实例,即使这个类的字节码事先未知。
  2. 访问私有字段和方法:可以访问类的私有(private)字段和方法。
  3. 动态调用方法:可以调用任何对象的方法,无论其访问权限是什么。
  4. 获取类的信息:可以获取类的名称、字段、方法等信息。
  5. 实现通用数组:可以动态地创建和操作数组。
  6. 实现泛型类的类型检测:可以在运行时检测泛型的类型。

如何使用反射

  1. 获取 Class 对象 :要使用反射,首先需要获取想要操作的类的 Class 对象。这可以通过直接使用 .class 来获取,或者通过实例的 getClass() 方法。

    复制代码
  2. 创建对象实例 :使用 Class 对象的 newInstance() 方法(Java 9 之前)或 getDeclaredConstructor().newInstance() 方法(Java 9 及以后)来创建类的实例。

    复制代码
  3. 访问字段 :使用 getField()getDeclaredField() 方法来获取字段的 Field 对象,然后使用 set()get() 方法来访问字段的值。

    复制代码
  4. 调用方法 :使用 getMethod()getDeclaredMethod() 方法来获取方法的 Method 对象,然后使用 invoke() 方法来调用方法。

    复制代码
  5. 获取类的信息 :使用 Class 对象提供的方法,如 getName()getFields()getMethods() 等,来获取类的信息。

    复制代码

使用反射的注意事项

  • 性能开销:反射通常比直接代码调用要慢,因为它涉及到类型检查和动态解析。
  • 安全问题:反射可以破坏封装性,允许代码访问私有字段和方法,这可能会带来安全风险。
  • 编译时检查:使用反射调用方法时,会丧失一些编译时的类型检查,可能导致运行时错误。

在实际应用中,反射通常用于框架和库的开发,例如 ORM(对象关系映射)、依赖注入、单元测试等场景。

相关推荐
秃头佛爷1 小时前
Python学习大纲总结及注意事项
开发语言·python·学习
阿伟*rui1 小时前
配置管理,雪崩问题分析,sentinel的使用
java·spring boot·sentinel
待磨的钝刨1 小时前
【格式化查看JSON文件】coco的json文件内容都在一行如何按照json格式查看
开发语言·javascript·json
XiaoLeisj3 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck3 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei3 小时前
java的类加载机制的学习
java·学习
励志成为嵌入式工程师4 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉4 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer4 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq4 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端