对象只能new吗?傻瓜、海王都是会五六种方式

  • J3 - 西行
  • Java(对象创建)

绝对不是标题党,我真能用五六种方式创建出对象出来,只不过是在 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 被影响到了,就像交到了个新对象而不用担心她是你前任。

好了,一口气搜罗了全网最全的交对象方式,希望掌握这些方式之后,女神随便交、单身不复返

今天的内容到这里就结束了,关注我,我们下期见

联系方式:

QQ:1491989462,做个好友,来个点赞之交。


  • 由于博主才疏学浅,难免会有纰漏,假如你发现了错误或偏见的地方,还望留言给我指出来,我会对其加以修正。

  • 如果你觉得文章还不错,你的转发、分享、点赞、留言就是对我最大的鼓励。

  • 感谢您的阅读,十分欢迎并感谢您的关注。

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

个人站点:J3

CSDN:J3 - 白起

掘金:J3-白起

知乎:J3-白起

这是一个技术一般,但热衷于分享;经验尚浅,但脸皮够厚;明明年轻有颜值,但非要靠才华吃饭的程序员。

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

J3code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值