zoukankan      html  css  js  c++  java
  • java 构造函数问题

    1、构造函数什么时候被调用,被谁调用?


    转摘:http://bbs.csdn.net/topics/350231037

    当然,只有在NEW的时候,才会真正的创建这个对象,只有在创建时才会调用该类的构造函数。
    如:
    Class A{
    public A(){
    System.out.println("这是A的构造函数");
    }
    }
    Class Test{
    public statics void main(String[] args){
    A a1;    //--->此时是不会打印出“这是A的构造函数”这段的
    a1=new A();    //此时会打印出来
    }
    }


    --------------------

    情况当然不限于此了。
    毕竟JAVA在创建对象时除了new的方式,还有反射的方式,就是
    Class.forName(完整类名)

    但反射加载时,只会调用类的无参
    构造函数。在反射时如果一个类中没有无参构造函数,那是会报实例化异常的。


    在同一个类中如果出现构造函数的重载,那也有可能出现其中一个调用另外一个的情况。最显著的情况是因为某些参数采用默认值的方式。

    还有创建子类对象时,会自动逐层调用父类的构造函数完成相关的初始化工作。



    ---------------------

    创建该类实例时,会调用类内部构造方法,其实也就是new
    上面有说反射的,反射的机制也是调用new关键字构造

    不过反射和new在分配上不同 反射是动态的


    String str="Me"  是不是分两步的?先是String str=null,然后str=new String("Me")


    Class.ForName("").newInstance就可以调用不带参数的构造函数。


    事实上例如在这样一个语句:Person ps=new Person();其实实例化了两个对象。Person ps是一个,new Person()是另一个。第一个ps其实就是一个引用其内部存储的是第二个对象的内存地址。所以第二个才是实体对象,所以new时才调用构造方法!!


    --------------------

    首先你要明白对象创建的几种方法:
    1.使用new关键字
    2.使用clone方法
    3.java的反射机制
    4.java的反序列化
    以上四种都可以产生java对象
    1,3都会明确的显式的调用构造函数
    2是在内存上对已有对象的影印 所以不会调用构造函数
    4是从文件中还原类的对象 也不会调用构造函数


    -------------------

    一般情况下,对象可以通过这三种方式创建:
    1、构造函数,当然就是NEW的时候调了
    2、拷贝构造函数,又有三种情况会调到,作为函数参数,作为返回值,用一个对象去创建另一个对象
    当然在JAVA里面Object类都是以引用方式传的,所以在JAVA里面基本上不会在函数调用的时候调用
    作为返回值会调用的,clone函数和用一个字符串对象去创建另一个字符串对象就是很好的例子
    3、操作符重载
    比如像String strHello = "HelloWorld";就是这样的,其实操作符重载也是一个函数

    当然,第2和第3太难,JAVA里面都把下层的给屏蔽掉了,但是在下层还是会这样执行的,所以好多人都说C++难就是这些方面


    ------------------

    1 JVM自动创建对象,不需要人为干预.
    2 new操作符
    3 Class.newInstance(Args)
    4 Constructor 对象就是用来创建对象的


    java中创建对象要通过new来实现,而构造函数只会在创建对象是才会被调用


    只能这么说,万象不离本质,本质上都是通过NEW来创建一个对象,而得到一个对象的方式却可以有多种,并不一定要通过NEW来获得,可以通过设计模式中的单件模式获得一个实例,但内部实现代码无非都是通过NEW来实现的,所以不要给外表骗了,要懂得实质。
    最后总结(NEW是本质,其他方式(比如getInstance、反射等)是通过封装后得到的现象)请区分好两者,希望对楼主有帮助。


    -------------------

    package constructor;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    public class TestConstructor {
    	public static void main(String[] args){
    		System.out.println("========= test new ==========");
    		Bean b1 = testNew();
    		b1.setId(1);
    		b1.setName("b1");
    		System.out.println(b1);
    		System.out.println("========= test newInstance ==========");
    		Bean b2 = testNewInstance();
    		b2.setId(2);
    		b2.setName("b2");
    		System.out.println(b2);
    		System.out.println("========= test clone ==========");
    		Bean b3 = testClone(b1);
    		b3.setName("b3");
    		System.out.println(b3);
    		System.out.println("========= test serializeBean&unserializeBean ==========");
    		serializeBean(b1);
    		Bean b4 = unserializeBean();
    		b4.setName("b4");
    		System.out.println(b4);
    	}
    	
    	public static Bean testNew(){
    		Bean b = new Bean();
    		return b;
    	}
    	public static Bean testNewInstance(){
    		try {
    			Bean b = Bean.class.newInstance();
    			return b;
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return null;
    	}
    	public static Bean testClone(Bean bean){
    		try {
    			Bean b = (Bean)bean.clone();
    			return b;
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return null;
    	}
    	
    	public static void serializeBean(Bean bean){
    		try {
    			FileOutputStream fos = new FileOutputStream("bean.ser");
    			ObjectOutputStream oos = new ObjectOutputStream(fos);
    			oos.writeObject(bean);
    			oos.close();
    			fos.close();
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    	public static Bean unserializeBean(){
    		try {
    			FileInputStream fis = new FileInputStream("bean.ser");
    			ObjectInputStream ois = new ObjectInputStream(fis);
    			Bean b = (Bean)ois.readObject();
    			return b;
    		} catch (FileNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (ClassNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		return null;
    	}
    }
    
    class Bean implements Cloneable, Serializable{
    	private static final long serialVersionUID = 8017660448545672348L;
    	int id;
    	String name;
    	
    	Bean(){
    		this(-1, "No Name");
    		System.out.println("--Bean() called--");
    	}
    	public Bean(int id, String name){
    		this.id = id;
    		this.name = name;
    		System.out.println("--Bean(int id, String name) called--");
    	}
    	
    	public String toString(){
    		StringBuffer sb = new StringBuffer("Bean@").append(this.hashCode())
    			.append("[id:").append(id).append("; name:'").append(name).append("']");
    		return sb.toString();
    	}
    	public int getId() {
    		return id;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	@Override
    	protected Bean clone() throws CloneNotSupportedException {
    		System.out.println("-----clone["+this+"]-----");
    		return (Bean)super.clone();
    	}
    }

    输出:

    ========= test new ==========
    --Bean(int id, String name) called--
    --Bean() called--
    Bean@25899876[id:1; name:'b1']
    ========= test newInstance ==========
    --Bean(int id, String name) called--
    --Bean() called--
    Bean@31131058[id:2; name:'b2']
    ========= test clone ==========
    -----clone[Bean@25899876[id:1; name:'b1']]-----
    Bean@5442802[id:1; name:'b3']
    ========= test serializeBean&unserializeBean ==========
    Bean@25699763[id:1; name:'b4']




    最初对象的产生,是new或者怎样到内存的,clone和serialized是内存数据的指向或拷贝?最终的本质,都是数据。类似c的malloc,分配一片内存给数据对象。指针或引用,也是占用内存,只是内存的内容是实际对象的地址。

  • 相关阅读:
    XtraFinder在OSX10.11的使用
    meterpreter > migrate 1548
    meterpreter > ps
    meterpreter > sysinfo
    meterpreter > screenshot
    ubuntu
    一次真是渗透
    nmap -sT -A --script=smb-check-vulns -PO 172.16.21.170
    use scanner/smb/smb_version
    scanner/portscan/syn
  • 原文地址:https://www.cnblogs.com/ycpanda/p/3637208.html
Copyright © 2011-2022 走看看