首页 > 编程语言 >Java中对象创建的几种方式

Java中对象创建的几种方式

时间:2023-09-01 19:25:29浏览次数:36  
标签:Java 构造方法 People 创建 class people Unsafe 几种 public

Java中对象创建的几种方式

  • 本文记录Java创建对象的种方式,详细内容请查看代码
测试对象
  • 粘贴复制即可,配合TestPeople食用
import java.io.Serializable;

/**
 * @author unknown
 * @since 2023/09/01 16:09
 */
public class People implements Cloneable , Serializable {

    private int age;

    private String name;


    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    /**
     *
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public People() {
        System.out.println("调用了无参构造方法");
    }

    protected People(int age, String name) {
        this.name = name;
        this.age = age;
        System.out.println("调用了有参构造方法");
    }

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }


}

测试示例
import org.junit.jupiter.api.Test;
import sun.misc.Unsafe;

import java.io.*;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/**
 * <P>对象的几种创建方式测试</P>
 * @author unknown
 * @since 2023/09/01 16:13
 */

public class TestPeople {


    /**
     * <P>new关键字创建</P>
     */
    @Test
    public void TestNew (){

        People people = new People();
        System.out.println(people);
    }

    /**
     * <P>克隆创建</P>
     * 如果使用使用此方式创建,对象必须实现Cloneable并且重写Object的clone方法
     * @see com.example.blog.test.base.People
     *
     */
    @Test
    public void TestClone () throws CloneNotSupportedException {

        // 在行克隆后,引用类型的克隆是引用地址值,基本类型的则是复制值,并不会调用对象的构造方法. 此方法称为-浅克隆
        People clone = (People) new People(1,"张三").clone();
        // 当运行此方法后会发现控制台输出了-> 调用了有参构造方法,这个输出是关键字new使用的有参构造方法,并不是在克隆时调用People的构造方法创建clone对象
        System.out.println(clone);
    }

    /**
     * <P>序列化创建</P>
     * 如果使用使用此方式创建,对象必须实现Serializable接口
     * @see com.example.blog.test.base.People
     */
    @Test
    public void TestSerializable () throws IOException, ClassNotFoundException {

        People people = new People(1, "张三");
        System.out.println(people);

        // 序列化
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectInputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectInputStream.writeObject(people);
        byte[] byteArray = byteArrayOutputStream.toByteArray();

        // 反序列化,在反序列化的时候,并不会调用People的构造方法
        ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(byteArray));
        People deserializable = (People)inputStream.readObject();
        System.out.println("反序列化"+deserializable);
    }

    /**
     * <P>反射创建</P>
     * 利用有参构造方法创建,在给定形参类型和参数值的时候,一定要按照People有构造方法的顺序给定
     */
    @Test
    public void testReflex () throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {

        // 获取有参的构造器
        Constructor<People> declaredConstructor = People.class.getDeclaredConstructor(int.class, String.class);
        // 假设对象的有参构造方法是private修饰的,那就无法利用构造器创建对象,以下是解决方法
//         declaredConstructor.setAccessible(true);
        // 利用有参构造器创建对象
        People people = declaredConstructor.newInstance(1, "张三");
        System.out.println(people);

    }

    /**
     * <P>MethodHandle API创建</P>
     * 利用有参构造方法创建,在给定形参类型和参数值的时候,一定要按照People有构造方法的顺序给定
     */
    @Test
    public void TestMethodHandles () throws Throwable {

        // 利用methodHandle给定类型创建构造器
        MethodHandle constructor = MethodHandles.lookup().findConstructor(People.class, MethodType.methodType(void.class, int.class, String.class));
        // 利用有参构造器创建对象
        People people = (People)constructor.invoke(1,"1" );
        System.out.println(people);
    }

    /**
     * <P>Unsafe创建</P>
     * Unsafe可以直接访问系统内存资源、自主管理内存资源等,慎用!
     * @see sun.misc.Unsafe
     */
    @Test
    public void TestUnsafe () throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {

        //创建Unsafe对象
        Class<Unsafe> unsafeClass = Unsafe.class;

        // 第一种方式:通过构造器获取Unsafe实例
        Constructor<Unsafe> declaredConstructor = unsafeClass.getDeclaredConstructor();
        // 假设对象的有参构造方法是private修饰的,那就无法利用构造器创建对象,以下是解决方法
        declaredConstructor.setAccessible(true);
        Unsafe unsafe1 = declaredConstructor.newInstance();
        People people = (People)unsafe1.allocateInstance(People.class);
        people.setName("张三");
        System.out.println(people);

        // 第二种方法:通过字段获取Unsafe实例
        Field theUnsafe = unsafeClass.getDeclaredField("theUnsafe");
        // 假设对象的有参构造方法是private修饰的,那就无法利用构造器创建对象,以下是解决方法
        theUnsafe.setAccessible(true);
        Unsafe unsafe2 = (Unsafe)theUnsafe.get(null);
        People people1 = (People)unsafe2.allocateInstance(People.class);
        people.setName("李四");
        System.out.println(people1);

    }

}

标签:Java,构造方法,People,创建,class,people,Unsafe,几种,public
From: https://www.cnblogs.com/ChenQ2/p/17672691.html

相关文章

  • JavaScript阶段易踩坑--层级覆盖--var与let使用--事件流(捕获和冒泡)
    刚刚走完JavaScript阶段,感觉挺爽的。但在总结的时候,我发现一些在做网页中容易错的地方,还有一些比较重要的方面。为了避免其他人在这一阶段也遇到这些问题。我今天就着重说一下在JavaScript这一阶段我容易出现的问题,从而让大家在遇到相同问题的时候可以快速解决。一.盒子覆盖问题只......
  • JavaScript中exec()方法详解
    一、RegExp对象的声明及exec()方法的使用声明一个RegExp有两种方式:1)varre=newRegExp(pattern,modifiers);2)varre=/pattern/modifiers;注释:pattern(模式):描述了表达式的模式modifiers(修饰符)用于指定全局匹配、区分大小写的匹配和多行匹配,具体有i、g和m三类,这三类也......
  • java上传文件大小限制 java实现大文件上传
    ​ 一. 大文件上传基础描述:WEB框架中,对于浏览器上传文件的请求,都有自己的处理对象负责对Http MultiPart协议内容进行解析,并供开发人员调用请求的表单内容。比如:框架中使用类似CommonsMultipartFile对象处理表二进制文件信息。.NET 中使用HtmlInputFile/ HttpPostedFile......
  • oracle 创建、查看、修改、删除、赋权directory目录
    如下:directory用于数据泵导入、导出创建的目录。1、查询directory目录select*fromdba_directories;2、创建或者修改directory目录createorreplacedirectory目录名称as'/存放目录路径'3、赋权directory目录grantread,writeondirectory目录名称t......
  • 【校招VIP】java语言考点之关键字static
    考点介绍:static考点是面试的高频考点,一般从容易到难提问,比如从static的含义和理解、到JVM的存储或者到线程安全性,再到单例模式等。答案详情解析和文章内容可扫下方海报二维码或点击链接即可查看!一、考点题目1、在java中,类Cat里面有个公有方法sleep(),该方法前有static修饰,则可......
  • Java错题记录1
    下列对接口的说法,正确的是()A:接口与抽象类是相同的概念B:若要实现一个接口为普通类则必须实现接口的所有抽象方法C:接口之间不能有继承关系D:一个类只能实现一个接口 正确答案:B A接口与抽象类是不同的概念。抽象类是用于捕捉子类的通用特性,接口是抽象方法......
  • Kingbase双实例创建方法
    第一个实例正常安装kingbase即可第二个实例,再次安装,选择不同于第一个实例的安装路径首先创建好两个不同的实例1.打开CMD创建服务sccreatekingbase8_instance1binPath="E:\kingbase1\Server\bin\sys_ctl.exe"(新实例路径)2.打开注册表regedit找到HKEY_LOCAL_MACHINE\SYSTE......
  • MapReduce 中的两表 join 几种方案简介
    1.概述在传统数据库(如:MYSQL)中,JOIN操作是非常常见且非常耗时的。而在HADOOP中进行JOIN操作,同样常见且耗时,由于Hadoop的独特设计思想,当进行JOIN操作时,有一些特殊的技巧。本文首先介绍了Hadoop上通常的JOIN实现方法,然后给出了几种针对不同输入数据集的优化方法。2.常见的join方法介......
  • Java-泛型
    1.泛型介绍泛型的本质是参数化类型,这样在具体使用的时候可以临时确定是什么类型。泛型可以应用在类、接口、方法、集合中,被称为泛型类、泛型接口、泛型方法。Java在语法上支持泛型,但是在编译阶段会进行所谓的“类型擦除”(TypeErasure),将所有的泛型表示(尖括号中的内容)......
  • 没有苹果开发者账号能否创建ios证书-最新
    ​ 摘要:本文介绍了在没有Mac电脑的情况下,使用appuploader工具生成iOS证书和描述文件的方法。随着大前端和H5框架的热门话题,越来越多的人希望将H5应用打包成iOS应用。苹果官方提供的证书申请方法需要Mac电脑,因此本文介绍了使用appuploader工具来生成证书的方便方法。   ......