绝对不是标题党,我真能用五六种方式创建出对象出来,只不过是在 Java 中。
当然,我也绝非海王,这毋庸置疑😛😛😛。
那,为啥出这篇文章呢!这就要看看下面这种图了。
(出自《疯狂Java讲义》一书)
这句话是没错的,一点问题都没有,但确引起了我的另一个思考。除了 new 这种人人都会的方式创建对象以外,还有没有其它别的方式来创建对象呢!答案是有的。
因为 Java 支持反射,则我们可以通过反射来创建出一个对象出来(其中有两种);
因为 Java 有序列化机制,则我们可以通过对象序列化的方式来创建出一个对象出来(其中有一种);
因为 Java 有一个超类支持 clone 方法,则我们有得到了一种创建对象的方法(一种);
因为 … 没有因为了,海王也就只知道这么多。
以上所有方式加起来一共五种创建对象的方式(如果各位还有其它方式,欢迎留言学习在🤩🤩🤩…)。
下面我会用每种方式各创建一个对象出来,喜欢用那种就看各位看官了。
1、new 关键字方式
日常开发中,相信通过关键字的方式来创建对象,是最常见的了。
这种方式简单又直白,告诉了千万单身的开发狗,这段代码的作者就是想要个对象,示例如下。
对象类(有对象才能创建,就像…先要有女生,你才能找对象(排除性别取向不正常可能)):
@Data public class GirlFriend { private String name; private Integer age; private Integer height; private Integer weight; @Override public String toString() { return "女朋友介绍{" + "姓名=" + name + ", 年龄=" + age + ", 身高=" + height + "cm, 体重=" + weight + "kg" + '}'; } }
创建对象代码:
public class GirlFriendTest { public static void main(String[] args) { // 创建一个对象!!!!!!! GirlFriend girlFriend = new GirlFriend(); // 竭尽所能,丰富她的属性 girlFriend.setName("刘亦菲"); girlFriend.setAge(18); girlFriend.setHeight(170); girlFriend.setWeight(50); // 完美对象,输出:女朋友介绍{姓名=刘亦菲, 年龄=18, 身高=170cm, 体重=50kg} System.out.println(girlFriend); } }
2、Class 对象方式
Class 是一个类的模板,它描述了这个类的所有信息。通常我们可以在一些源码中看到它的使用身影,当然本人也时常会使用该方法(抽工具类或写组件的时候)。
这时候,拿到这个 Class 对象也是比较有考量的,通常有下面三种:
- Class aClass = Class.forName("全限定类名");
- Class aClass = 类名.class;
- Class aClass = 具体实例对象.getClass();
创建对象代码:
public class GirlFriendTest { public static void main(String[] args) throws Exception { // 根据没朋友模板,创建出对象出来 GirlFriend girlFriend = GirlFriend.class.newInstance(); // 竭尽所能,丰富她的属性 girlFriend.setName("刘诗诗"); girlFriend.setAge(18); girlFriend.setHeight(165); girlFriend.setWeight(48); // 完美对象,输出:女朋友介绍{姓名=刘诗诗, 年龄=18, 身高=165cm, 体重=48kg} System.out.println(girlFriend); } }
3、构造器对象方式
上面第二种说了, Class 是类的模板,它描述了一个类中所有的信息,其中就有我们想要的构造器对象信息。
这种方式,根据类模板信息从中拿到类的构造器信息(Constructor
),然后再通过构造器信息创建出具体的对象。
创建对象代码:
public class GirlFriendTest { public static void main(String[] args) throws Exception { // 先拿到模板中,所有构造器信息 Constructor<?>[] declaredConstructors = GirlFriend.class.getDeclaredConstructors(); // 取第一个构造器,创建出对象出来 GirlFriend girlFriend = (GirlFriend) declaredConstructors[0].newInstance(); // 竭尽所能,丰富她的属性 girlFriend.setName("范冰冰"); girlFriend.setAge(18); girlFriend.setHeight(175); girlFriend.setWeight(58); // 完美对象,输出:女朋友介绍{姓名=范冰冰, 年龄=18, 身高=175cm, 体重=58kg} System.out.println(girlFriend); } }
4、Object 对象的 clone() 方式
Java 语法中,每个类从定义出来,就天生默认继承一个超类 ——— Object.class。
在 Object 类中就有一个返回对象功能的方法 clone() 。该方法规定目标类要实现 Cloneable 接口,并重写 Object 类中的 clone() 方法,最终就会返回一个新的对象。
那我们改造一下咱们的女朋友类。
@Data public class GirlFriend implements Cloneable { // 实现 Cloneable 接口 private String name; private Integer age; private Integer height; private Integer weight; /** * 重写 clone 方法 * @return */ @Override public GirlFriend clone() { GirlFriend girlFriend = null; try { girlFriend = (GirlFriend) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return girlFriend; } @Override public String toString() { return "女朋友介绍{" + "姓名=" + name + ", 年龄=" + age + ", 身高=" + height + "cm, 体重=" + weight + "kg" + '}'; } }
创建对象代码:
public class GirlFriendTest { public static void main(String[] args) throws Exception { GirlFriend girlFriend = new GirlFriend(); // 竭尽所能,丰富她的属性 girlFriend.setName("刘亦菲"); girlFriend.setAge(18); girlFriend.setHeight(170); girlFriend.setWeight(50); // 完美对象,输出:女朋友介绍{姓名=刘亦菲, 年龄=18, 身高=170cm, 体重=50kg} System.out.println(girlFriend); // 克隆一个对象出来 GirlFriend clone = girlFriend.clone(); // 稍加装饰 clone.setName("杨幂"); // 完美对象,输出:女朋友介绍{姓名=杨幂, 年龄=18, 身高=170cm, 体重=50kg} System.out.println(clone); } }
根据结果我们可以知道,这种方式同样可以生成两个不同的对象(但还是浅拷贝,这里不做过多介绍),所以不用担心克隆出来的还是指向同一内存地址。
5、序列化方式
Java 中经常需要对数据进行传输,而 Java 中数据往往存在类对象中,这要如何传输呢!
方法就是将对象进行序列化,形成一个对象流写到 IO 流中,从而进行一个数据传输,最终会在终点的时候将这个流又反序列化成一个新的对象获取数据(RPC 调用等)。
在这序列化与反序列化中,就不知不觉的创建了个新对象了,而序列化前规定了序列化对象必须要实现 Serializable 接口。那我们还是要先改造女朋友对象,代码如下。
@Data public class GirlFriend implements Serializable { // 实现序列化 Serializable 接口 private String name; private Integer age; private Integer height; private Integer weight; @Override public String toString() { return "女朋友介绍{" + "姓名=" + name + ", 年龄=" + age + ", 身高=" + height + "cm, 体重=" + weight + "kg" + '}'; } }
创建对象代码:
public class GirlFriendTest { public static void main(String[] args) throws Exception { GirlFriend girlFriend = new GirlFriend(); // 竭尽所能,丰富她的属性 girlFriend.setName("刘亦菲"); girlFriend.setAge(18); girlFriend.setHeight(170); girlFriend.setWeight(50); // 完美对象,输出:女朋友介绍{姓名=刘亦菲, 年龄=18, 身高=170cm, 体重=50kg} System.out.println(girlFriend); // 将对象序列化一下,方便传输 ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("order.obj")); os.writeObject(girlFriend); // 再反序列化,不知不觉又生成一个新对象 ObjectInputStream is = new ObjectInputStream(new FileInputStream("order.obj")); GirlFriend o1 = (GirlFriend) is.readObject(); // false System.out.println(girlFriend == o1); // 定制新对象属性 o1.setName("高圆圆"); // 完美对象,输出:女朋友介绍{姓名=高圆圆, 年龄=18, 身高=170cm, 体重=50kg} System.out.println(o1); } }
这种序列化方式可以实现一个对象的深拷贝,这就不用担心改变对象 A 而害怕对象 B 被影响到了,就像交到了个新对象而不用担心她是你前任。
好了,一口气搜罗了全网最全的交对象方式,希望掌握这些方式之后,女神随便交、单身不复返
。
今天的内容到这里就结束了,关注我,我们下期见