Java对象生成方式
最近面试,有一道题考的是java的对象是否必须通过构造方法生成。当时可能是脑子进水了,像C里面可以直接内存拷贝,然后用指针引用就可以视为生成了一个新对象,java虽然不提供这种危险的方式,但是肯定也有类似方式,所以答案肯定是是否然的。那么就列一下以下几种对象生成方式,如果后面有其他方式那么后续补充。
public class Tclass implements Serializable,Cloneable { /** * */ private static final long serialVersionUID = -2146400774304662925L; Tclass(){ System.out.println("Tclass constructor invoked"); } @Override public Tclass clone(){ try { return (Tclass)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } }
上面是测试的类,顺便记下,之前将Tclass这个类作为内部类 来用,发现就算实现了Serializable接口序列化还是会报错,可能跟外部类挂钩,这里先不多说注意一下即可。
下面是测试几种生成对象的方法的代码:
@Test public void testGetObject(){ System.out.println("start generate test1---------------"); Tclass test1=new Tclass(); System.out.println("end generate test1---------------"); System.out.println("start generate test2---------------"); Tclass test2=test1.clone(); System.out.println("end generate test2---------------"); Tclass test3=null; Tclass test4=null; try(ByteArrayOutputStream os=new ByteArrayOutputStream(); ObjectOutputStream oos=new ObjectOutputStream(os); ) { oos.writeObject(test1); byte[] results=os.toByteArray(); try(ObjectInputStream ois=new ObjectInputStream(new ByteArrayInputStream(results));) { System.out.println("start generate test3---------------"); test3=(Tclass)ois.readObject(); System.out.println("end generate test3---------------"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { System.out.println("start generate test4---------------"); test4=(Tclass) Class.forName("lm.Tclass").newInstance(); System.out.println("end generate test4---------------"); } catch (InstantiationException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (IllegalAccessException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (ClassNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.println("test1 is :"+test1); System.out.println("test2 is :"+test2); System.out.println("test3 is :"+test3); System.out.println("test4 is :"+test4); }
最终打印结果为:
start generate test1---------------
Tclass constructor invoked
end generate test1---------------
start generate test2---------------
end generate test2---------------
start generate test3---------------
end generate test3---------------
start generate test4---------------
Tclass constructor invoked
end generate test4---------------
test1 is :lm.Tclass@20d547f8
test2 is :lm.Tclass@22067303
test3 is :lm.Tclass@5568db68
test4 is :lm.Tclass@571cb4a6
可以看出,test1和test4使用new 和 反射方式调用,实际上都是调用构造方法生成对象的方式。而通过clone和反序列化生成对象是不调用构造方法的。

浙公网安备 33010602011771号