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

简介: 绝对不是标题党,我真能用五六种方式创建出对象出来,只不过是在 Java 中。当然,我也绝非海王,这毋庸置疑😛😛😛。


绝对不是标题党,我真能用五六种方式创建出对象出来,只不过是在 Java 中。

当然,我也绝非海王,这毋庸置疑😛😛😛。


那,为啥出这篇文章呢!这就要看看下面这种图了。

(出自《疯狂Java讲义》一书)


image.png


这句话是没错的,一点问题都没有,但确引起了我的另一个思考。除了 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 被影响到了,就像交到了个新对象而不用担心她是你前任。


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


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

目录
相关文章
|
7月前
|
设计模式 算法 安全
一文带你通俗理解23种软件设计模式(推荐收藏,适合小白学习,附带C++例程完整源码)
一文带你通俗理解23种软件设计模式(推荐收藏,适合小白学习,附带C++例程完整源码)
187 0
|
3天前
|
存储 JSON 前端开发
【工作中问题解决实践 十二】使用@JsonTypeInfo实现请求数据对象多态
【工作中问题解决实践 十二】使用@JsonTypeInfo实现请求数据对象多态
71 0
|
6月前
|
人工智能 自然语言处理 算法
赶紧学大模型!再不学连对象都找不到了。。。
这次云栖大会的几个笑点之一了,我认为这也能带来一些思考,根据量子位的调研看目前AI大模型工程师的缺口确实很大,这也很可能是计算机行业的下一个风口了。
|
9月前
|
存储 算法 编译器
【C++技能树】再也不怕没有对象了 --初识类
我们先来看看C语言解决一个问题的过程。
46 0
|
12月前
|
存储 安全 Java
基础一:一切都是对象
基础一:一切都是对象
71 0
|
存储 数据采集 算法
库调多了,都忘了最基础的概念-方法篇
库调多了,都忘了最基础的概念-方法篇
102 0
库调多了,都忘了最基础的概念-方法篇
|
前端开发 JavaScript
前端百题斩【016】——原型、构造函数和实例之间的奇妙关系
前端百题斩【016】——原型、构造函数和实例之间的奇妙关系
前端百题斩【016】——原型、构造函数和实例之间的奇妙关系
|
存储 Java
【漫画】Java对象的创建和访问全过程详解(上)
【漫画】Java对象的创建和访问全过程详解
105 0
【漫画】Java对象的创建和访问全过程详解(上)
|
Java
【漫画】Java对象的创建和访问全过程详解(下)
【漫画】Java对象的创建和访问全过程详解
96 0
【漫画】Java对象的创建和访问全过程详解(下)
|
Java C++
保守VS开放?看清封装对象属性 | 带你学《Java面向对象编程》之四
高楼万丈,起于平地。本节通过对比正反几个实例剖析了封装对象属性的必要性,介绍了进行封装的基本原则。
保守VS开放?看清封装对象属性   |  带你学《Java面向对象编程》之四