1.在使用new关键字创建某个类的实例对象时,构造方法抛出了异常,这时候,程序有没有在内存中创建出该类的实例对象呢?请说出理由!
2.对于一个类中的构造方法来说,是否要考虑与该类中的其他方法之间的线程安全吗?请说出理由!
3.如果程序中没有任何变量引用一个外部类对象,但有变量引用其中的内部类对象,请问外部类对象是否会被垃圾回收器回收?请说明理由!

解决方案 »

  1.   

    1,创建了对象,当new一运行,虚拟机就直接给改对象分配空间,这个抛出异常一般是在给这个对象初始化时候发生的异常。只要虚拟机给这个对象分配了空间,就形成了一个对象。在这个对象初始化完成后,再将引用(变量)指向该空间的地址。中途出现异常,则初始化未完成,或者其他的异常,总之没有将引用指向地址。而一段时间后gz会自动回收这个没有引用指向的对象。2,一般不需要,new的时候只是给对象初始化值,一般用不到方法。静态的方法虽在new的时候可能会加载,但一般也不需要考虑线程安全(至少我没有碰到过)。3,会回收,分配空间的时候有几个class分配几个单独的空间。也就是外部类的对象和内部类对象是没有关系的,当外部类对象没有引用时gz会自动回收其空间
      

  2.   

    3.如果程序中没有任何变量引用一个外部类对象,但有变量引用其中的内部类对象,请问外部类对象是否会被垃圾回收器回收?请说明理由!如何引用的?new A().new AA() ?? new AA() ?
      

  3.   

    第一题测试结果,证明了可以生成对象package cs;public class ObjectTest {
    public static void main(String[] args) {
    Object obj=new Object("abc");
    System.out.println(obj.getString());
    }}
    class Object{
    private String string;
    public Object(String string){
    this.string=string;
    try {
    throw new Exception();
    } catch (Exception e) {
    }
    }
    public String getString() {
    return string;
    }
    public void setString(String string) {
    this.string = string;
    }
    }第二题,不用考虑与该类中的其他方法之间的线程安全,如果你用synchronized修饰构造方法会出现编译错误Illegal modifier for the constructor in type Object; only public, protected & private are permitted.
    如果在构造方法内部写synchronized(this){//do something},这样是不会出错的,但是毫无意义,两个线程同时能生成对象,但是其中一个执行到synchronized(this){//do something}时会停滞,直到另一个线程执行完此代码块,但这样做并不能保证构造方法与其他方法之间的线程安全.
      

  4.   

    3.如果程序中没有任何变量引用一个外部类对象,但有变量引用其中的内部类对象,请问外部类对象是否会被垃圾回收器回收?请说明理由!
    红字是不是指直接new的对象,而没有此对象的引用?like this
    new Outer();
    而不是
    Outer outer=new Outer();
    如果是不生成对象的意思,该问题是有问题的7楼好像是说的这意思
    如果是new Outer();的话该对象不会被垃圾回收器回收public class Outer {
    Outer.inner inner;
    public void print(){
    inner=this.new inner();
    System.out.println(inner);
    }
    class inner{

    }
    protected void finalize(){
    System.out.println(this+"被回收了");
    }
    public static void main(String[] args) {
    while(true){
    new Outer().print();//有inner对象输出是Outer对象还没被回收
    }
    }
    }
      

  5.   

    朋友,别的问题我不会,我只会第一个,就算构造方法产生异常了,对象也照样会创建的,以为new X();这一步分解成字节指令码后,其实是有两个关键不骤的,第一个new,第二个是invokespecial。其中new的意思就是在堆上为该对象分配一块内存,然后把各个成员变量的初始值设置好(int设成0,String设成null),最后把该对象的引用(一般是一个字长)变量压入JAVA栈。OK,到此new指令的任务就完成了。然后invokespecial指令是调用该对象的构造方法,把堆中对象的初始值设成你想要的值,如果没有指定构造方法,JVM会直接调用每个类默认的那个无参构造方法。所以当构造方法抛出了异常了,那就是在第二部invokespecial指令出错了,可能你指定好的变量初始值没能成功的设置,但是因为new指令执行过了,所以堆内存中肯定出现了该类的一个对象,JAVA栈中肯定也有一个引用指向该对象,只不过该对象的字段的初始值全都是默认的,而不是你想要的罢了。
      

  6.   

    第三题貌似我试了下没被回收。
    因为还是能够被调用。public class InnerDemo05{
    public static void main(String args[]){
    Outer.Inner in = new Outer.Inner();
    Outer out = new Outer();
    String str = in.getName();
    System.gc();
    System.out.println(out.info);
    in.fun();

    }
    }
    class Outer{
        String info = "hello";

    static class Inner{
    private String name;
    public void fun(){
    System.out.println("内部类"); 
    }
    public String getName(){
    return name;
    }
    }
    public void fun1(){
    System.out.println("外部类"); 
    System.out.println(info); 
    }
    }
      

  7.   

    利用上面兄弟们的代码试了,有静态内部类的那个,外部类被回收了,17楼没被回收,是因为少了把那个引用赋空。
    我的输出是Outer@1fa1bb6被回收了,如果内部类不是静态的,还没试public class AllTest{
        public static void main(String args[]){
            Outer.Inner in = new Outer.Inner();
            Outer out = new Outer();
            String str = in.getName();
            out=null;
            System.gc();        
        }
    }
    class Outer{
        String info = "hello";
        static class Inner{
            private String name;
            public void fun(){
                System.out.println("内部类"); 
            }
            public String getName(){
                return name;
            }
        }
        public void fun1(){
            System.out.println("外部类"); 
            System.out.println(info); 
        }
        protected void finalize(){
            System.out.println(this+"被回收了");
        }
    }
      

  8.   

    刚刚抱歉了,第一次插入javacode。。没反应过来
    关于第三问,下面这个我试了试内部类为public,非静态,这样必须与外部类联系起来,所以即使外部类的引用没了,可是估计他还被内部类给连着呢,所以没被回收(代码仅有细小改动)
    public class AllTest{
        public static void main(String args[]){
            Outer out = new Outer();
            Outer.Inner in = out.new Inner();
            String str = in.getName();
            out=null;
            System.gc();        
        }
    }
    class Outer{
        String info = "hello";
        public class Inner{
            private String name;
            public void fun(){
                System.out.println("内部类"); 
            }
            public String getName(){
                return name;
            }
        }
        public void fun1(){
            System.out.println("外部类"); 
            System.out.println(info); 
        }
        protected void finalize(){
            System.out.println(this+"被回收了");
        }
    }