精华内容
下载资源
问答
  • Java创建对象详解:Java创建对象的几种方法

    万次阅读 多人点赞 2019-05-10 20:01:32
    Java 对象的生命周期包括创建、使用和清除,本文详细介绍对象的创建,在 Java 语言中创建对象分显式创建与隐含创建两种情况。 显式创建对象 对象的显式创建方式有 4 种。 1. 使用 new 关键字创建对象 这是常用的创建...

    对象是对类的实例化。对象具有状态和行为,变量用来表明对象的状态,方法表明对象所具有的行为。Java 对象的生命周期包括创建、使用和清除,本文详细介绍对象的创建,在 Java 语言中创建对象分显式创建隐含创建两种情况。
    显式创建对象
    对象的显式创建方式有 4 种。
    1. 使用 new 关键字创建对象
    这是常用的创建对象的方法,语法格式如下:
    类名 对象名=new 类名();
    2. 调用 java.lang.Class 或者 java.lang.reflect.Constuctor 类的 newlnstance() 实例方法
    在 Java 中,可以使用 java.lang.Class 或者 java.lang.reflect.Constuctor 类的 newlnstance() 实例方法来创建对象,代码格式如下:
    java.lang.Class Class 类对象名称=java.lang.Class.forName(要实例化的类全称);
    类名 对象名=(类名)Class类对象名称.newInstance();

    调用 java.lang.Class 类中的 forName() 方法时,需要将要实例化的类的全称(比如 com.mxl.package.Student)作为参数传递过去,然后再调用 java.lang.Class 类对象的 newInstance() 方法创建对象。
    3. 调用对象的 clone() 方法
    该方法不常用,使用该方法创建对象时,要实例化的类必须继承 java.lang.Cloneable 接口。 调用对象的 clone() 方法创建对象的语法格式如下:
    类名对象名=(类名)已创建好的类对象名.clone();

    4. 调用 java.io.ObjectlnputStream 对象的 readObject() 方法
    例 1
    下面创建一个示例演示常用的前三种对象创建方法。示例代码如下:

    public class Student implements Cloneable
    {   
        //实现 Cloneable 接口
        private String Name;    //学生名字
        private int age;    //学生年龄
        public Student(String name,int age)
        {    //构造方法
            this.Name=name;
            this.age=age;
        }
        public Student()
        {
            this.Name="name";
            this.age=0;
        }
        public String toString()
        {
            return"学生名字:"+Name+",年龄:"+age;
        }
        public static void main(String[] args)throws Exception
        {
            System.out.println("---------使用 new 关键字创建对象---------");
           
            //使用new关键字创建对象
            Student student1=new Student("小刘",22);
            System.out.println(student1);
            System.out.println("-----------调用 java.lang.Class 的 newInstance() 方法创建对象-----------");
           
            //调用 java.lang.Class 的 newInstance() 方法创建对象
            Class cl=Class.forName("Student");
            Student student2=(Student)cl.newInstance();
            System.out.println(student2);
            System.out.println("-------------------调用对象的 clone() 方法创建对象----------");
            //调用对象的 clone() 方法创建对象
            Student student3=(Student)student2.clone();
            System.out.println(student3);
        }
    }
    
    

    对上述示例的说明如下:
    使用 new 关键字或 Class 对象的 newInstance() 方法创建对象时,都会调用类的掏造方法。
    使用 Class 类的 newInstance() 方法创建对象时,会调用类的默认构造方法,即无参构造方法。
    使用 Object 类的 clone() 方法创建对象时,不会调用类的构造方法,它会创建一个复制的对象,这个对象和原来的对象具有不同的内存地址,但它们的属性值相同。
    如果类没有实现 Cloneable 接口,则 clone。方法会抛出 java.lang.CloneNotSupportedException 异常,所以应该让类实现 Cloneable 接口。

    程序执行结果如下:

    ---------使用 new 关键字创建对象---------
    学生名字:小刘,年龄:22
    -----------调用 java.lang.Class 的 newInstance() 方法创建对象-----------
    学生名字:name,年龄:0
    -------------------调用对象的done()方法创建对象----------
    学生名字:name,年龄:0
    

    隐含创建对象
    除了显式创建对象以外,在 Java 程序中还可以隐含地创建对象,例如下面几种情况。
    ①String strName=“strValue”,其中的“strValue”就是一个 String 对象,由 Java 虚拟机隐含地创建。
    ②字符串的“+”运算符运算的结果为一个新的 String 对象,示例如下:
    String str1=“Hello”;
    String str2=“Java”;
    String str3=str1+str2; //str3引用一个新的String对象
    ③当 Java 虚拟机加载一个类时,会隐含地创建描述这个类的 Class 实例。

    **提示:**类的加载是指把类的 .class 文件中的二进制数据读入内存中,把它存放在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Class 对象,用来封装类在方法区内的数据结构。

    无论釆用哪种方式创建对象Java 虚拟机在创建一个对象时都包含以下步骤:

    1. 给对象分配内存。
    2. 将对象的实例变量自动初始化为其变量类型的默认值。
    3. 初始化对象,给实例变量赋予正确的初始值。

    **注意:**每个对象都是相互独立的,在内存中占有独立的内存地址,并且每个对象都具有自己的生命周期,当一个对象的生命周期结束时,对象就变成了垃圾,由 Java 虚拟机自带的垃圾回收机制处理。

    展开全文
  • java创建一个对象步骤

    2018-02-15 13:29:11
  • 老师说,先new了一个对象,在堆内存中开辟空间 然后就是赋默认值(没有静态代码块) 接着就是调用对应的构造函数进栈。 执行隐藏的步骤。 1:super() 2:对非静态变量进行赋显示值 3:执行构造代码块 最后执行构造...
  • 可以看完这个图就懵了,以下是创建对象的六个步骤: 1、判断是否能在常量池中能找到类符号引用,并检查是否已被加载、解析、初始化(即判断类元信息是否存在) 如果没有则在双亲委派模式下,使用当前类加载器以...


    要看的懂对象的创建过程,首先你得有对Java虚拟机和Java基础以及JUC很是熟悉,
    比如类的加载过程、CAS、多线程、JVM的GC等等

    首先来看一个图,我大概会根据图中的内容来分享这六个步骤(其实几个步骤不重要,只要包括的内容都在就行):

    在这里插入图片描述

    一、创建对象的六个步骤:

    1、判断是否能在常量池中能找到类符号引用,并检查是否已被加载、链接、初始化(即判断类元信息是否存在)

    如果没有则在双亲委派模式下,使用当前类加载器以ClassLoader + 包名 + 类名为Key进行查找对应的.class文件以此来完成类的加载进内存。在这个过程中,要是找不到要加载的类JVM就会抛出ClassNotFoundException异常,意思就是找不到该类进行加载。

    2、为对象分配内存空间

    首先计算对象占用空间大小,接着在堆中划分一块内存给新对象,如果实例成员变量是引用变量,仅分配引用变量空间即可,即4个字节。文章结束附有Java八种基本数据类型的所占字节数,分配内存时根据堆中内存是否规整分为:

    内存规整—指针碰撞:如果是规整的,那么虚拟机将采用指针碰撞法来为对象分配内存。

    意思就是所有用过的内存在一边,空闲的内存在另一边,中间放着一个指针作为分界点的指示器,分配内存就仅仅是把指针向空闲那一边挪动一段与对象大小相等的距离,以此来分配内存给对象。如果垃圾收集器选择的是Serial、ParNew这种基于标记 - 压缩算法的,也就是一般使用带有compact(整理)过程的收集器时,就会使用指针碰撞分配方法。

    另外:为什么内存就会是规整的呢?或者为什么内存有不规整的呢?我写了一篇我觉得十分完整的JVM垃圾回收篇

    内存不规整—空闲列表:如果内存不是规整的,已使用的内存和未使用的内存相互交错,那么虚拟机将采用这种空闲列表法给对象分配内存。

    意思就是虚拟机维护了一个列表,记录上哪些内存块是可用的,再分配的时候从列表找到一块足够大的空间划分给对象实例,这种分配方式就是空闲列表(Free List)。

    3、处理并发问题
    为什么会有这个阶段呢?就是我们都知道堆空间是多个线程共享的,那么多个线程同时去操作堆空间数据时就会存在并发线程安全问题。

    两种方式去解决这种并发安全问题:
    采用CAS失败重试、区域加锁更新的原子性

    CAS算法是这样的:CAS(Compare-and-Swap),即比较并替换,是一种实现并发算法时常用到的技术,Java并发包(Java.Util.Concurrent)中的原子类都使用了CAS技术。

    CAS需要有3个操作数:内存地址V,旧的预期值A,即将要更新的目标值B。
    CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作。

    大白话:假如A线程要把共享变量sum的值从1修改为2,那么这时候A线程会先通过地址去获取一次sum的初始值1作为预期值,在修改之前会把之前获取的预期值与当前sum的值进行一次比较,假如两个值相同,那就将1修改为2,如果在A线程修改之前,B线程进入把sum的值提前修改为0了,那么A线程在用预期值去与当前的sum值0比较,显然两个值不相等,此时的A线程就不会修改,会继续去读取sum的值,直到sum为 1 时才进行修改操作。

    每个线程预先分配一块TLAB区域,可以通过-XX:+ /-UseTLAB参数来设定

    TLAB这一块区域是在堆当中Eden(伊甸园)区中的,大概占整个Eden区的1%左右,很小的一块区域,堆为每一个线程单独分配一块TLAB,以此来保证多线程共享数据时是线程安全的。

    4、初始化分配到的空间(对属性初始化,零值初始化)

    这一过程说白了就是:所有属性设置默认值,保证对象实例字段在不赋值时可以直接使用。基本数据类型默认初始化的值在文章下方表格里。

    5、设置对象的对象头

    将对象的所属类(即类的元数据信息)、对象的HashCode、对象的GC信息、锁信息等数据存储在对象头中。这个过程的具体设置方式取决于JVM实现。

    6、执行init方法进行初始化

    可以简单理解成调用构造函数进行显示的赋值,代码中和构造器中初始化。在Java程序的视角看来,初始化才正式开始,初始化成员变量,显示赋值,执行实例化代码块,调用类的构造器,并把堆内对象的首地址赋值给引用变量。

    一般来说(由字节码中是否跟随有invokspecial 指令所决定), new指令之后会接着就是执行方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算完全创建出来。

    扩展:还有一个clinit方法,这个方法是加载时对类中static静态修饰的属性和静态代码块进行初始化(此过程是在链接阶段的准备阶段)。这是JVM相关的知识了。

    二、对象头的内部结构

    1、创建了Customer()实例 和 Account()实例
    在这里插入图片描述
    一个对象的内存结构包括:运行时元数据、类型指针、实例数据、对齐填充


    2、对象头里包括(64位机器占96位)运行时元数据(Mark Word)(占64位)、类型指针(Klass Point)(占32位)

    (1) 运行时元数据里又包括:哈希值(HashCode)、GC分代年龄、锁状态标志

    哈希值:31位的对象标识hashCode,采用延迟加载技术。调用方法System.identityHashCode()计算,并会将结果写到该对象头中。它是一个地址,用于栈对堆空间中对象的引用指向,不然栈是无法找到堆中对象的;

    GC分代年龄(占4位):记录幸存者区对象被GC之后的年龄age,一般age为15(阈值为15的原因是因为age只有4位最大就可以将阈值设置15)之后下一次GC就会直接进入老年代,要是还没有等到年龄为15,幸存者区就满了怎么办,那就下一次GC就将大对象或者年龄大者直接进入老年代。

    锁状态标志:记录一些加锁的信息(我们都是使用加锁的话,在底层是锁的对象,而不是锁的代码,锁对象的话,那会改变什么信息来表示这个对象被改变了呢?也就是怎么才算加锁了呢?

    答案就是改变这个对象的对象头的锁信息来标识已经加锁,下一个线程来获取是获取不到的,底层是通过比对当前的线程的那个值与它所期望的值是否相同,这时候一直自旋直到与期望值相同,相同就获取到锁,反之则进入到阻塞队列等待,这个机制叫做CAS,比较并交换。)
    在这里插入图片描述
    那么怎样查看对象的对象头的信息呢 ?

    第一步:导入第三方依赖

        <dependency>
          <groupId>org.openjdk.jol</groupId>
          <artifactId>jol-core</artifactId>
          <version>0.11</version>
        </dependency>
    

    第二步:打印信息

    System.out.println(ClassLayout.parseInstance(o).toPrintable());
    

    打印结果:

    在这里插入图片描述
    其中VALUE分析:
    在这里插入图片描述

    另外:锁的状态有两位数的空间标识,这样就可以实现用较少的空间去存储更多的信息,
    0 表示不可偏向,1 表示可偏向

    标志位锁状态
    01未锁定
    00轻量级
    10重量级(膨胀)
    01可偏向
    11GC标记

    (2)类型指针:是对方法区中类元信息的引用

    3、实例数据:真实记录一个对象包含的数据,比如说一个person对象,里面可能包含年龄、性别、身高等等,其中数据为字符串的,要引用到字符串常量池。

    想知道jdk8字符串常量池到底在那个地方存储的可以看这里。

    4、对齐填充:填充部分仅起到占位符的作用, 原因是HotSpot要求对象起始地址必须是8字节的整数,假如不是,就采用对齐填充的方式将其补齐8字节整数倍,那么为什么是8呢?原因是64位机器能被8整除的效率是最高的。
    在这里插入图片描述
    另外这个过程还会涉及到逃逸分析。我写了一篇逃逸分析的具体作用,感兴趣可以看看。

    基本数据类型所占字节数默认值包装类名称
    byte1(1字节=8位)0Byte
    short20Short
    int40Integer
    long80LLong
    double80.0dDouble
    float40.0fFloat
    char2‘\u0000’Character
    boolean1falseBoolean

    怎样快速记住这些类型的方法,请看这里。

    有用点个关注,手留余香!😐 😐 😐

    展开全文
  • JVM-JAVA对象创建的五个步骤

    千次阅读 2020-06-29 10:03:01
    对象创建的五个步骤 1、类加载检查 虚拟机遇到一条 new 指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有...

    对象创建的五个步骤

    • 1、类加载检查

    虚拟机遇到一条 new 指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执行相应的类加载过程。

    总结为 if(new指令的参数不在常量池 || 此符号引用的类没有被加载、解析和初始化)--------->{执行相应类加载}

    • 2、分配内存

    在类加载检查完成后,虚拟机为new出来的对象分配内存。
    新对象需要的内存大小在类加载完成后就已经确定,现在要做的是吧一块确定大小的内存从Java堆中划分出来。
    分配方式涉及到两种:
    指针碰撞空闲列表
    堆内存规整时堆内存不规整时
    用过的内存放在一边,没用的放一边,中间有个分界值指针JVM维护一个列表记录划分的内存
    GC收集器:Serial、ParNewGC收集器:CMS

    堆内存规整与否取决于GC收集器的算法是标记-清除、还是标记-整理

    创建对象时涉及到的问题:

    线程安全:先TLAB再 CAS+失败重试
    • CAS+失败重试: CAS 是乐观锁的一种实现方式。所谓乐观锁就是,每次不加锁而且假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。虚拟机采用 CAS 配上失败重试的方式保证更新操作的原子性。
    • TLAB: 为每一个线程预先在 Eden 区分配一块儿内存,JVM 在给线程中的对象分配内存时,首先在 TLAB 分配,当对象大于 TLAB 中的剩余内存或 TLAB 的内存已用尽时,再采用上述的 CAS 进行内存分配
    • 3、初始化零值

    内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这一步操作保证了对象的实例字段在 Java 代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。
    • 4、设置对象头

    虚拟机要对对象进行必要的设置,例如这个对象是那个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。 这些信息存放在对象头中。 另外,根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。
    • 5、执行init方法

    经过1-4步骤,从JVM的角度看一个新的对象已经产生,但从Java程序上看,对象创建才刚开始。执行 new 指令之后会接着执行 方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算完全产生出来。
    展开全文
  • Java创建对象的过程简介

    千次阅读 2016-12-02 11:17:42
    简单记录一下Java创建对象的过程,就是new一个对象的时候发生了哪些事情。Java程序执行的过程在此不作说明,对象的创建过程只是程序执行过程的一部分。有关整个程序执行的过程,等熟悉了虚拟机之后在作说明。
  • Java创建对象的四种方式

    万次阅读 多人点赞 2016-05-09 16:47:56
     另外,如果我们不想利用默认构造器来创建java对象,而想利用指定的构造器来创建java对象,则需要利用Construtor对象,每个Construtor对应一个构造器,为了利用指定构造器来创建java对象,需要如下三个步骤: ...
  • Java创建一个对象步骤

    千次阅读 2019-04-18 22:13:53
    3,在堆内存创建对象, 4,给对象中属性默认初始化值(基本数据类型为0,引用数据类型为null) 5,属性进行显示初始化 6,构造方法进栈,对对象中的属性赋值,构造方法弹栈 7,将对象的地址值赋值给s ...
  • java对象创建过程

    2012-04-29 10:36:10
    详细介绍java对象创建过程,以致对java基础详细的掌握!
  • Java对象创建的流程

    千次阅读 2019-05-07 22:05:39
    文章目录Java对象创建的流程1.Java普通对象创建1.1new指令1.2分配内存1.3初始化1.4对象的初始设置1.5\方法2.Java对象内存布局2.1对象头2.2实例数据2.3对齐填充 1.Java普通对象创建 这里讨论的仅仅是普通Java...
  • java对象创建过程

    万次阅读 多人点赞 2018-09-03 20:54:02
    大家都知道,java使用new 关键字进行对象创建,但这只是从语言层次上理解了对象创建,下边我们从jvm的角度来看看,对象是怎么被创建出来的,即对象创建过程。 对象创建大概分为以下几步: 1:检查类是否...
  • 下面我们详细了解Java程序中new一个普通对象时,HotSpot虚拟机是怎么样创建这个对象的,包括5个步骤:相应类加载检查过程、在Java堆中为对象分配内存、分配后内存初始化为零、对对象进行必要的设置、以及执行对象...
  • ① 最常见的方式就是直接 new 加构造器的方式创建 ② 变形一:XXX(类名). 静态方法,本质这种方式还去调用类中构造器,比如说:单例模式、日历类(Calendar) 和一些工具类等等。 ③ 变形二:XXXBuilder / ...
  • 创建对象步骤和方法

    千次阅读 2018-05-21 16:10:34
    创建对象步骤①为对象分配内存空间,将对象的实例变量初始化为其变量类型的默认值②如果实例变量在声明时被显式的初始化则将初始化值赋给实例变量③调用构造方法④返回对象的引用创建对象的方式①类名 对象名=new ...
  • java创建对象:new和newInstance的不同

    千次阅读 2012-09-27 13:41:09
    它们的区别在于创建对象的方式不一样,前者是使用类加载机制,后者是创建一个新类。那么为什么会有两种创建对象方式?这主要考虑到软件的可伸缩、在初始化一个类,生成一个实例的时候,newInstance()方法和new关键字...
  • Java有哪些创建对象的方式? 1、用new关键字创建对象,需要使用构造器。 2、使用反射机制创建对象,用Class类或Constructor类的newInstance()方法。 3、通过object类的clone方法 4、使用反序列化
  • Java对象创建的具体过程

    千次阅读 2017-07-09 14:31:59
    Java是一门面向对象的编程...在语言层面上,创建对象(例如克隆、反序列化)通常仅仅是一个new关键字而已,而在虚拟机中,对象(文中讨论的对象限于普通Java对象,不包括数组和Class对象等)的创建又是怎样一个过程呢?
  • JAVA对象创建过程

    千次阅读 2019-08-01 18:00:16
    在图中可以清楚的看到jvm在创建对象时候的执行流程,下面具体讨论一下每个步骤: 在程序进行加载的时候,他的类信息,常量,静态变量等数据就会存放在方法区(常量池)中。 在执行new操作的时候,就会去方法区去...
  • 今天正式开始学习java,今天接触并记录下来的知识主要是关于java基础语法中和C语言不同的点。 1.在java中char类型变量占2字节,也就是说,char类型保存的变量都将以2字节形式存在,包括数字、字符、英文字母等。 ...
  • Java通过反射创建对象

    万次阅读 2012-07-26 15:50:01
    一、通过反射创建不带参数的对象 这个比较简单,不需要获取这个类的构造方法类,不需要指明构造参数的参数列表。下面是要使用的类和方法,使用步骤如下: Class(类): Class 类的实例表示正在运行的 Java 应用...
  • java通过反射创建对象的两种方式

    千次阅读 2019-03-07 15:44:05
    java中,通过反射创建对象有两种方式 使用Class对象的newInstance()方法来创建对象; 具体步骤是 1、获取类的Class对象(有三种方式可以获取,可以自行百度一下) 2、通过调用所获取到的Class对象的newInstance...
  • java--创建对象三步

    千次阅读 2017-03-01 14:53:03
    创建对象 对象是根据类创建的。在Java中,使用关键字new来创建一个新的对象。创建对象需要以下三步: 声明:声明一个对象,包括对象名称和对象类型。实例化:使用关键字new来创建一个对象。初始化:使用new创建...
  • java对象创建(内存模型)过程详解

    千次阅读 2017-04-09 14:35:58
    java对象创建详细过程步骤、jvm内存结构:声明对象引用和创建对象实体。类信息、对象引用、对象实体均在内存的不同区域。 内存结构 每一个java应用程序均会唯一的对应一个jvm实例,而这个jvm实例将会完成对象的内存...
  • Java反射机制创建对象

    万次阅读 多人点赞 2014-04-08 18:48:46
    import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; class Person { private String name; private int age; public Person(String name
  • JVM 如何创建Java对象

    千次阅读 2015-08-04 20:38:02
    Java程序中,创建一个对象通常需要一个new关键字就够了,但是在虚拟机中,这个过程却有点复杂,这里面包括了类加载、内存分配、初始化零值等等一系列的步骤。 下面来看看JVM如何创建一个对象(这里面的对象仅仅...
  • Java程序运行和对象创建过程简述

    千次阅读 2017-06-22 22:12:47
    Java中一个对象创建分为两个步骤: 加载类,创建对象。 加载类是将所写的程序.java文件编译生成的.class文件加载到内存中,保证了对象创建的预置环境。类加载完毕后才可以创建该类的对象。 第一步:加载类 1. 当开始...
  • java面向对象

    万次阅读 多人点赞 2018-08-21 16:51:59
    包括面向对象概念、类与对象的关系、封装、构造函数、this关键字、static关键字、单例设计模式、继承、多态、内部类、异常、包等java基础知识。 1、面向对象 面向对象是相对面向过程而言 面向对象和面向过程都是...
  • 今天看别人的博客,讲到面试相关的问题,其中有一个知识点是:synchronized关键字,Java对象头、Markword概念、synchronized底层实现,monitorenter和monitorexit指令,一脸蒙逼,虽然早期把《深入理解Java虚拟机》...
  • Android NDK c创建java对象

    千次阅读 2015-04-23 19:53:49
    1.得到需要创建对象的类 2.(从1的类中)得到构造方法 3.调用构造方法,这样就得到了一个jobject对象 JNIEXPORT void JNICALL Java_com_aii_ndk_NativeObject_nativeNewJavaObject( JNIEnv *env, jobject thiz)1...
  • java new对象创建过程

    万次阅读 2018-07-29 07:00:54
    关于对象创建过程一般是从new指令(我说的是JVM的层面)开始的(具体请看图1),JVM首先对符号引用进行解析,如果找不到对应的符号引用,那么这个类还没有被加载,因此JVM便会进行类加载过程(具体加载过程可参见我的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 407,354
精华内容 162,941
关键字:

java创建对象的步骤

java 订阅