我们知道,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!