发现了一个java创建对象的知识点,吓得我赶紧记下来

我们知道,java是面向对象编程,一句顺口溜是什么来着?万物皆对象!

你想查看属性(非静态),怎么查?要对象!

你要调用方法(非静态),怎么调用?要对象!

没对象,真惨啊!o(╥﹏╥)o,啥都干不了~~

于是,没对象我们就new一个啊!没对象我们就创造一个对象!

这也就是对象的创建了,我们今天就来好好说下,这么整到“对象”的,还没对象的需要好好看看这个了!

1、使用关键字new

当你创建一个Class类的时候,其实是默认创建一个无参的构造方法。当然你也可以自己根据需要重载一个构造方法,那样默认的无参构造方法,自然是失效的,这个时候,若是想要调用无参构造方法,那只能再手写一个无参构造方法了。上个代码来看下(*^▽^*)。

public class BeautifulGirl {

    private Integer age;

    private String height;

    private String name;

    public Integer getAge() {
        return age;
    }

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

    public String getHeight() {
        return height;
    }

    public void setHeight(String height) {
        this.height = height;
    }

    public String getName() {
        return name;
    }

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

下面来调用下

 public static void main(String[] args) throws Exception {
        BeautifulGirl beautifulGirl = new BeautifulGirl();
        beautifulGirl.setAge(20);
        beautifulGirl.setHeight("175cm");
        System.out.println(JSON.toJSONString(beautifulGirl));
    }

//输出
//{"age":20,"height":"175cm"}

这样当然是没我问题的,这也是我们最常用的得到对象的方式,但是,有些对象的参数就是不能为空,比如这个BeautifulGirl,肯定是要有名字的啊,于是,构造方法重载。

   public BeautifulGirl(String name) {
        this.name = name;
    }

这个时候,你再new,就要写参数了,不然会提示BeautifulGirl(String) in BeautifulGirl cannot be applied to () ,所以一般在重载构造方法的时候,都会把无参构造方法也写上,防止某个地方想要new对象,new不出来啊,哈哈哈。

2、使用反射

还是这个BeautifulGirl,我们不使用new,利用java的反射来构建下这个对象。

public static void main(String[] args) throws Exception {
        Class<?> bClass = Class.forName("com.pindao.ehr.center.operateVO.BeautifulGirl");
        Object o = bClass.newInstance();
        if (o instanceof BeautifulGirl) {
            BeautifulGirl beautifulGirl = (BeautifulGirl) o;
            beautifulGirl.setAge(20);
            System.out.println("beautifulGirl:"+JSON.toJSONString(beautifulGirl));
        }
    }

欸?居然报错?这种基础的反射还会出问题?贴出来看下

Exception in thread "main" java.lang.InstantiationException: com.pindao.ehr.center.operateVO.BeautifulGirl
	at java.lang.Class.newInstance(Class.java:427)
	at com.pindao.ehr.center.operateVO.TempTest.main(TempTest.java:9)
Caused by: java.lang.NoSuchMethodException: com.pindao.ehr.center.operateVO.BeautifulGirl.<init>()
......

可以看到,报错的地方是newInstance这里,提示是NoSuchMethodException,没有这样的方法的异常!哦,原来是没有实例化这个类的方法,实例化不就是调用构造方法么?仔细一看,哎,构造方法被我重载了,不是无参的,newInstance明明只要无参的构造方法啊!吓得我赶紧把无参构造方法补上。

再来运行一下,于是,20岁的美丽girl出来啦!

{"age":20}

Process finished with exit code 0

当然利用反射换种写法也是可以的

         ClassLoader loader = ClassLoader.getSystemClassLoader();
                  Class<?> aClass = 
                  loader.loadClass("com.pindao.ehr.center.operateVO.BeautifulGirl");
        Object o = aClass.newInstance();
        if (o instanceof BeautifulGirl) {
            BeautifulGirl beautifulGirl = (BeautifulGirl) o;
        }
        
        //--------------------------------------------------------

        BeautifulGirl t = new BeautifulGirl();
        
        Class<? extends BeautifulGirl> aClass1 = t.getClass();
        BeautifulGirl beautifulGirl = aClass1.newInstance();

3、clone()与序列化

clone()这个方法大家可能有点陌生,但是Object这个类大家总不陌生吧?Object是所有类的父类,而Object又有自己的一些方法,其中就有equals,wait,notify,toString等等。既然对象是继承Object的,那么自然可以重写Clone方法,然后新建一个对象,不过这个也要对象调用。还要重写方法,这个使用的应该不多。

还有就是序列化,这个的话,就需要实现Serializable这个序列化接口了,一些RPC调用,参数的接收都是使用序列化与反序列化的,这个这里就不多说了,东西太多,如果大家有兴趣的话,可以去看下序列化和反序列化。

4、使用Unsafe

不管是new还是反射,亦或是Clone,甚至一些序列化方法中也都要使用到对象的无参构造方法,如果没有无参构造方法,那么这个BeautifulGirl对象自然是木有了,那么我现在非要一个BeautifulGirl对象咋办?

别担心,有招!

对象BeautifulGirl跑不了!

我们还有Unsafe 工具包!我们使用反射直接来找到BeautifulGirl对象!

由于在Gson中已经对有对这中方式的实例构建进行封装了,我就不重新写了,大家看下效果!

 public static void main(String[] args) throws Exception {

        Map<Type, InstanceCreator<?>> instanceCreators = new HashMap<>();
        ConstructorConstructor constructorConstructor = new ConstructorConstructor(instanceCreators);

        ObjectConstructor<BeautifulGirl> constructor = constructorConstructor.get(TypeToken.get(BeautifulGirl.class));
        BeautifulGirl beautifulGirl = constructor.construct();
        beautifulGirl.setName("jingjing");
        beautifulGirl.setAge(20);
        beautifulGirl.setHeight("175cm");
        System.out.println(JSON.toJSONString(beautifulGirl));
    }

执行结果(无参构造已经覆盖):

{"age":20,"height":"175cm","name":"jingjing"}

Process finished with exit code 0

好了,有兴趣的可以去看下Gson的源码,今天说到这里,继续回去看Unsafe去!o(* ̄︶ ̄*)o

No sacrifice,no vectory!

猜你喜欢

转载自blog.csdn.net/zsah2011/article/details/112557331