当前位置: 首页 > 新闻动态 > 网络资讯

在Java里如何创建和使用对象_Java对象创建与使用流程说明

作者:P粉602998670 浏览: 发布日期:2026-02-01
[导读]:Java中创建对象的三种常见方式是new、反射和反序列化:new调用构造方法并触发类初始化;反射(如getDeclaredConstructor().newInstance())绕过编译检查但可能抛异常;反序列化不调用构造方法,跳过静态块和构造逻辑。
Java中创建对象的三种常见方式是new、反射和反序列化:new调用构造方法并触发类初始化;反射(如getDeclaredConstructor().newInstance())绕过编译检查但可能抛异常;反序列化不调用构造方法,跳过静态块和构造逻辑。

Java中对象创建的三种常见方式

Java里创建对象最常用的是new关键字,但实际开发中还会遇到反序列化、反射等场景,不同方式行为差异明显。

  • new ClassName():调用类的构造方法,触发类初始化(如果尚未初始化),是最直接、最可控的方式
  • Class.forName("ClassName").newInstance()(已弃用)或clazz.getDeclaredConstructor().newInstance():绕过编译期检查,适用于插件、框架扩展,但可能抛NoSuchMethodExceptionIllegalAccessException
  • 反序列化(ObjectInputStream.readObject()):不调用任何构造方法,直接分配内存并填充字段值,因此静态块和构造逻辑不会执行——这点常被忽略,导致单例被破坏或资源未初始化

对象使用前必须确认类已加载与初始化

看似简单的new操作背后有明确的类加载阶段顺序:加载 → 验证 → 准备 → 解析 → 初始化。其中“初始化”阶段才执行static代码块和static变量赋值。

  • 若类中含static { System.out.println("init"); },首次new该类实例时才会输出,而非编译或第一次引用类名时
  • 通过Class.forName("X")默认会触发初始化;而ClassLoader.loadClass("X")不会——这是动态加载时控制初始化时机的关键区别
  • 使用javap -c查看字节码可验证:每个new指令后紧跟着dupinvokespecial(即构造方法调用)

常见错误:对象为null却直接调用方法

这不是语法错误,而是运行时NullPointerException的高发源头,尤其在依赖注入失败、条件分支遗漏或集合取值未判空时。

  • 不要写obj.toString(),先做if (obj != null)或用Objects.toString(obj)(后者对null返回字符串"null"
  • Spring中@Autowired字段为null,大概率是该类没走Spring容器管理(比如用new手动实例化),而非注解写错了
  • 局部变量未显式初始化(如String s;),编译直接报错;但成员变量会被默认初始化为null/0/false,容易掩盖逻辑缺陷

对象生命周期与引用类型的实际影响

Java对象是否被回收,不仅看new了多少次,更取决于可达性分析——而引用类型决定了GC时的处理策略。

  • StrongReference(普通= new X()):只要强引用存在,GC绝不回收
  • WeakReference:GC时无论内存是否充足都会回收,适合做缓存(如WeakHashMap
  • SoftReference:内存不足时才回收,比弱引用“软”一点,曾用于图片缓存,但JDK 12+后回收策略更不可控,慎用
  • PhantomReference:无法通过它获取对象实例,仅用于跟踪对象被

    回收的时机,必须配合ReferenceQueue
WeakReference wr = new WeakReference<>(new String("hello"));
System.gc(); // 不保证立即执行,但wr.get()很可能返回null
对象是否真正“可用”,取决于它有没有逃过GC、构造方法是否完整执行、以及所有依赖是否就绪——这些环节任何一个出问题,都可能让new出来的对象处于不可用状态。
免责声明:转载请注明出处:http://m.lexweb.cn/news/794354.html

扫一扫高效沟通

多一份参考总有益处

免费领取网站策划SEO优化策划方案

请填写下方表单,我们会尽快与您联系
感谢您的咨询,我们会尽快给您回复!