Java中创建对象的5种方式

想看更多请移步我的个人博客:Java中创建对象的5种方式 - 猿馆

方法是否调用构造方法
new关键字调用了构造方法
Class类的newInstance()方法调用了构造方法
Constructor类的newInstance()方法调用了构造方法
clone()没有调用构造方法
反序列化没有调用构造方法
1.使用new关键字

最常见 、 最简单 , 可调用任意的构造方法 (无参的和带参数的)

Example example = new Example();	// 调用无参构造方法 创建Example对象。
Example example = new Example("我是example ");	// 调用有参构造方法 创建Example对象。
2.使用Class类的newInstance()方法

只能调用无参的构造方法 创建对象、
弱类型的,效率比使用new低、

Class class =  Class.forName("com.pojo.Example");	// 首先得到 目标类的 Class类对象
Example example = class.newInstance();				// 调用Class类的  newInstance()方法,会调用目标类的默认构造方法,并返回一个目标对象

// 或者:
Example example = Example.class.newInstance(); //直接在类名后跟 .class,获取Class对象,再跟 .newInstance(),返回目标对象。
3.使用Constructor类的newInstance()方法

调用有参数的 和 私有的 构造方法

Example example = Example.class.getConstructor().newInstance(); //注意是getConstructor(),不是getConstructors()

上面是调用无参public构造方法,下面是调用有参public 和 有参非public 构造方法:

Constructor constructor2 = Example.class.getConstructor(String.class);	// 有String类型参数的public构造方法
Example example = constructor2.newInstance("sfasaffe");

Constructor constructor3 = Example.class.getConstructor(String.class);	// 有String类型参数的非public构造方法
constructor3 .setAccessible(true);   	// 要设置访问许可,不然没有权限访问private构造方法,会抛出异常
Example example = constructor3.newInstance("调用私有构造方法");

上面的两种newInstance()方法都抛出了异常,所以通过这种方法创建对象要进行异常处理。
这两种newInstance()被称为反射。

4.使用clone()方法

无论何时我们调用一个对象的clone方法,jvm就会创建一个新的对象,将前面对象的内容全部拷贝进去。用clone方法创建对象并不会调用任何构造方法 。

Example example = new Example ();
Example example2 = example.clone();

条件:实现Cloneable接口并实现其定义的clone()方法

注意,Java默认的clone()方法是浅拷贝

所谓浅拷贝,也就是对于数值类型(基本数据类型,如int、float…包括String)的成员变量,是拷贝值,对于对象类型(如数组、object…)的成员变量,是拷贝引用

也就是说,如果A对象有一个 List 类型的成员变量,那么它的拷贝对象B修改了自己List的值,原来A对象的 List 的值也会发生改变。

解决办法:在重写的clone()方法中手动 拷贝 对象类型 的成员变量
如:

public Example clone() throws CloneNotSupportedException{
	Example example = (Example)super.clone(); 
	example.arrayList = (ArrayList<String>) this.arrayList.clone();	// 注意,这里 手动拷贝的对象,必须也要实现Cloneable接口
	
	return example;
}
5.使用反序列化

当我们序列化和反序列化一个对象,jvm会给我们创建一个单独的对象。在反序列化时,jvm创建对象并不会调用任何构造方法 。

为了反序列化一个对象,我们需要让我们的类实现Serializable接口

ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.object"));
Example example = (Example ) in.readObject();
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值