Java对象的创建方式

17 篇文章 0 订阅

好久不更文了,今天聊一聊 Java 对象的创建方式,Java 对象创建一共有四种。

  • 关键字 new
  • 反射 newInstant()
  • Object 的 clone()
  • 序列化 readObject()

关键字 new

Student s = new Student();

这段代码看着是不是特别熟悉,稍微学过一点Java的都写过类似的代码的,也是我们最初实例化对象的方式,不做过多讲解,太简单,太基础。

反射 newInstant()

Student student = (Student) Class.forName("com.test.Student").newInstance();

你觉得这段代码陌生,我们来看下面这一段呢?

Class.forName("com.mysql.jdbc.Driver");

MySql 数据库的驱动加载总该用过了吧,是不是有一点熟悉的感觉?这种方式用的很多的,比如 Spring 的依赖注入。当然 Spring 的机制肯定比我的例子完善和复杂的。

Object 的 clone()

Student student = new Student("张三",2);
Student student1 = (Student) student.clone();

记得在 Student 里重写 clone(),并且实现接口(implements) Cloneable。

@Override
protected Object clone() throws CloneNotSupportedException {
    return super.clone();
}

请注意 clone() 方法的权限是 protected,所以这里需要手动重写一遍。不过应当注意,这个方法要慎用。如果条件允许,我建议使用下面这种方式手动拷贝。

public Student build() {
    Student student = new Student();
    student.name = new String(this.getName());
    student.age = this.age;
    return student;
}

调用方式

Student student = new Student("张三", 2);
Student student2 = student.build();

至于为什么要这样写,这牵涉到 clone() 的一些底层实现问题,感兴趣的可以自行搜索。

Student student = new Student("张三", 2);
Student student1 = (Student) student.clone();
Student student2 = student.build();
if (student.getName() == student1.getName()) {
    System.out.println("1");
}
if (student.getName() == student2.getName()) {
    System.out.println("2");
}

运行结果为 1,下图讲解释 clone() 的拷贝行为。
这里写图片描述
虽然本地方法执行效率比较快,但这个问题有些时候是致命的,还不好排查,踩过坑的人都懂。

序列化 readObject()

序列化要实现接口(implements) Serializable,这个是必需的,不然会报错,直接上代码。

Student student = new Student("张三", 2);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("demo.data"));
out.writeObject(student);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("demo.data"));
Student student3 = (Student) in.readObject();
in.close();
System.out.println("name:"+student3.getName()+",age:"+student3.getAge());

运行结果:name:张三,age:2,结果没有什么争议,内容也没有什么亮点。序列化的问题在于,可以从数据流中创建对象,这给不法分子创造了利用空间。个人不建议使用默认的序列化的,最好自定义序列化规则,在你需要序列化的 Class 里面添加如下的方法。

private void writeObject(ObjectOutputStream stream) throws IOException,ClassNotFoundException{
    stream.defaultWriteObject();//这里为了省事直接调用了默认的序列化方法,重写这个方法是最好的。
}

private void readObject(ObjectInputStream stream) throws IOException,ClassNotFoundException{
    stream.defaultReadObject();
}

总结

今天一共讲了四种创建对象方式,其中前两种都会显示的调用对象本身的构造函数,后面两种不会调用构造函数,可以自己尝试一下。

如有不对,欢迎留言!


欢迎大家关注我的微信公众号:卡戎
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值