站内搜索

搜索

06-02 13:26
05-31 17:11

八股文(java基础)

47

主题

38

点数

151

积分

地衡测影

积分
151

柴到了

发表于 2025-3-21 01:58:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x

反射

反射在程序运行期间动态获取类和操纵类的一种技术。通过反射机制,可以在运行时动态地创建对象、调用方法、访问和修改属性,以及获取类的信息。

invoke 方法的执行流程如下:

  • 查找方法:当通过 java.lang.reflect.Method 对象调用 invoke 方法时,Java 虚拟机(JVM)首先确认该方法是否存在并可以访问。这包括检查方法的访问权限、方法签名是否匹配等。
  • 安全检查:如果方法是私有的或受保护的,还需要进行访问权限的安全检查。如果当前调用者没有足够的权限访问这个方法,将抛出 IllegalAccessException。
  • 参数转换和适配:invoke 方法接受一个对象实例和一组参数,需要将这些参数转换成对应方法签名所需要的类型,并且进行必要的类型检查和装箱拆箱操作。
  • 方法调用:对于非私有方法,Java 反射实际上是通过 JNI(Java Native Interface,Java 本地接口)调用到 JVM 内部的 native 方法,例如 java.lang.reflect.Method.invoke0()。这个 native 方法负责完成真正的动态方法调用。对于 Java 方法,JVM 会通过方法表、虚方法表(vtable)进行查找和调用;对于非虚方法或者静态方法,JVM 会直接调用相应的方法实现。
  • 异常处理:在执行方法的过程中,如果出现任何异常,JVM 会捕获并将异常包装成 InvocationTargetException 抛出,应用程序可以通过这个异常获取到原始异常信息。
  • 返回结果:如果方法正常执行完毕,invoke 方法会返回方法的执行结果,或者如果方法返回类型是 void,则不返回任何值。

无实例化

// 1.反射得到对象
Class<?> clazz = Class.forName("User");
// 2.得到方法
Method method = clazz.getDeclaredMethod("publicMethod");
// 得到私有方法
Method privateMethod = clazz.getDeclaredMethod("privateMethod");
// 设置私有方法可访问
privateMethod.setAccessible(true);
// 执行私有方法
privateMethod.invoke(clazz.getDeclaredConstructor().newInstance());

实例化

// 1.反射得到对象
Class<?> clazz = Class.forName("User");
// 2.得到私有方法
Method privateMethod = clazz.getDeclaredMethod("privateMethod");
// 3.设置私有方法可访问
privateMethod.setAccessible(true);
// 4.得到实例
Object user = clazz.getDeclaredConstructor().newInstance();
// 5.执行私有方法
privateMethod.invoke(user);

克隆

在编程中,克隆是指创建一个与原始对象相同的新对象。这个新对象通常具有与原始对象相同的属性和方法,但是它们是两个不同的对象,它们在内存中的位置不同。 在 Java 中,可以通过实现 Cloneable 接口和重写 clone() 方法来实现对象的克隆

浅克隆

  • 克隆出来的新对象与原始对象共享引用类型的属性。也就是说,新对象中的引用类型属性指向的是原始对象中相同的引用类型属性。如果修改了新对象中的引用类型属性,原始对象中的相应属性也会被修改。在 Java 中,可以通过实现 Cloneable 接口和重写 clone() 方法来实现浅克隆。

    public class CloneDemo {
      public static void main(String[] args) {
          Person p1 = new Person();
          p1.setName("张三");
          p1.setAge(18);
          Address address = new Address();
          address.setCity("北京");
          p1.setAddress(address);
          // 克隆 p1 对象
          Person p2 = p1.clone();
          System.out.println(p1 == p2); // false
          System.out.println(p1.getAddress() == p2.getAddress()); // true
      }
    }
    class Person implements Cloneable {
      private String name;
      private int age;
      private Address address; // 引用类型
      @Override
      public Person clone() {
          Person person = null;
          try {
              person = (Person) super.clone();
          } catch (CloneNotSupportedException e) {
              e.printStackTrace();
          }
          return person;
      }
      // 忽略 getter 和 setter 方法
    }
    
    class Address {
      private String city;
    
      // 忽略 getter 和 setter 方法
    }

深克隆

  • 克隆出来的新对象与原始对象不共享引用类型的属性。也就是说,新对象中的引用类型属性指向的是新的对象,而不是原始对象中相同的引用类型属性。如果修改了新对象中的引用类型属性,原始对象中的相应属性不会被修改。
import lombok.Getter;
import lombok.Setter;

public class CloneDemo {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.setName("张三");
        p1.setAge(18);
        // 引用类型
        Address address = new Address();
        address.setCity("北京");
        p1.setAddress(address);
        // 克隆 p1 对象
        Person p2 = p1.clone();
        // 对比引用类型的地址值是否相同
        System.out.println(p1.getAddress() == p2.getAddress()); // false
    }
}

@Getter
@Setter
class Person implements Cloneable {
    private String name;
    private int age;
    private Address address; // 引用类型

    @Override
    public Person clone() {
        Person person = null;
        try {
            person = (Person) super.clone();
            // 克隆引用类型
            person.setAddress(person.getAddress().clone());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return person;
    }
}

@Getter
@Setter
class Address implements Cloneable {
    private String city;

    @Override
    public Address clone() {
        Address address = null;
        try {
            address = (Address) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return address;
    }
}

杂记

下面代码相等

import lombok.Builder;
@Builder
public class Student {
    private String name;
    private int age;
}

Student stu = Student.builder()
    .name("磊哥")
    .age(18)
    .build();
Student stu = GenericBuilder.of(Student::new)
                .with(Student::setName, "磊哥")
                .with(Student::setAge, 18)
                .build();
温馨提示:看帖回帖是一种美德,您的每一次发帖、回帖都是对论坛最大的支持,谢谢! [这是默认签名,点我更换签名]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入社群

加入社群

Pixtech

Powered by Pixtech

© 2025 Pixtech Team.