最近刚刚开始学JAVA,在看 JAVA 编程思想。前天遇到一个问题百思不得其解,只好上来请教一下大家。此问题是这样的,如果一个类的构造器限定为私有,那么它应该是不能直接在类的外部用 new 来进行初始化的。但如果这个类是一个内部类的情况下,却可以在这个内部类的外围类中直接用 new 来进行初始化,这是为什么呢?
// 不能直接生成类的对象。
package c08;class TestA {
private static int count = 2;
private TestA(int i){
System.out.println("TestA private construct"+i);
}
public static TestA MakeTestA()
{
if ( count <= 0 ) 
return null; //超过6个连接的话,不再分配相应的连接。
TestA out = new TestA(count);
         count--;
         System.out.println("This is the leaf  "+count+" Objects");
return  out;
}
}public class TestPrivateConstruct { public static void main(String[] args) {

         //TestA b = new TestA();    //会报错。
TestA[] a = new TestA[7] ;
 for ( int i=0 ; i< a.length;i++)
a[i] = TestA.MakeTestA();
}
}//同样情况在内部类的外围类中可以直接生成类的对象。//: c08:TestParcel.java
// Returning a reference to an inner class.
// From 'Thinking in Java, 3rd ed.' (c) Bruce Eckel 2002
// www.BruceEckel.com. See copyright notice in CopyRight.txt.class Parcel3 {
  private class PContents implements Contents {
    private int i = 11;
    public int value() { return i; }
  }
  protected class PDestination implements Destination {
    private String label;
    private PDestination(String whereTo) {
      label = whereTo;
    }
    public String readLabel() { return label; }
  }
  public Destination dest(String s) {
    return new PDestination(s);  //这里。
  }
  public Contents cont() {
    return new PContents();
  }
}public class TestParcel {
  public static void main(String[] args) {
    Parcel3 p = new Parcel3();
    Contents c = p.cont();
    Destination d = p.dest("Tanzania");
    // Illegal -- can't access private class:
    //! Parcel3.PContents pc = p.new PContents();
  }
} ///:~
想不太明白这是为什么啊。。
是因为接口的关系吗?

解决方案 »

  1.   

    楼主,我不太明白你的意思,你第一个例子定义的是private带有参数的构造函数,而你在实例化的时候是没有带参数,这个肯定编译不通过的。。
      

  2.   

    但如果这个类是一个内部类的情况下,却可以在这个内部类的外围类中直接用 new 来进行初始化,这是为什么呢?
    ------------------
    我是这样理解的:因为private 修饰一个方法时限定该方法只能在该类的内部被调用,
    而 内部类属于内部类,那么内部类可以调用外部类的private修饰的方法。
    所以内部类可以通过new()来创建具有private 修饰的构造方法的外部类。上面是我的理解,不知道正确不正确。其实这个只要记住就好了,没有必要钻牛角尖吧。
      

  3.   

    楼主所谓的错误其实不是private的错误,而是当你在“//TestA b = new TestA();    //会报错。
    ”时JAVA类会自动调用一个无参数的构造方法,而你的类TestA 中却没有这么一个方法,如果你的类中没有那个有参数的构造方法,系统会自动生成一个无参数的构造方法,反之就不会生成无参数的构造方法。
      

  4.   


    我是这样理解的:因为private 修饰一个方法时限定该方法只能在该类的内部被调用,
    而 内部类属于内部类,那么内部类可以调用外部类的private修饰的方法。
    所以内部类可以通过new()来创建具有private 修饰的构造方法的外部类。上面是我的理解,不知道正确不正确。其实这个只要记住就好了,没有必要钻牛角尖吧。
    ___________________________________________________内部类是可以不受限制的调用外部类中的私有方法。这个我已经验证过了。
    我主要是不明白的是。在 
    private PDestination(String whereTo) {
          label = whereTo;
        }
    中已经定义过了 PDestination 的构造方法是 private 的,为什么下面的  
    return new PDestination(s);  //这里。
    却可以在这个PDestination内部类的外面用这种方法得到PDestination的实例。从理论上说,这个时候,应该是看不到内部类的 private  的构造方法的。所以也应该是会报错的。但却没有。
    另外我也试过了,就算是不带参数的默认的 private PDestination() 也是可以直接用 NEW 进行实例化的。 
    而如果不是在内部类的外围类的情况下,
     //TestA b = new TestA();    //会报错。是一定会报错。只能用 类似 MakeTestA 的方法来得到实例。所以这就有一个问题, JAVA 是否对 private  的权限解释,也是根据对象的种类及上下文而会有所不同?
      

  5.   

    楼主,我不太明白你的意思,你第一个例子定义的是private带有参数的构造函数,而你在实例化的时候是没有带参数,这个肯定编译不通过的。。
    ---------------------------------
    哦。SORRY。。
    那个是疏忽了。。
    不过,即使改成private TestA(){
    System.out.println("TestA private construct");
    }
    下面也是一样不能
    TestA b = new TestA();   
    的。编译的时候就是会报错。
      

  6.   

    对于楼主的第一个问题,你的构造器是private的是一定不能在类外面通过new来产生对象的,一般是通过类内的方法来返回的,就想一楼说的那样为了控制创建对象的个数,
      

  7.   

    每一个类都会有一个.CLASS文件。所以和文件是一个还是几个没有太大的关系,所有的内部类也会产生一个对应的 .CLASS文件。第一个问题的确就是为了进行对并发到某个连接的控制而进行的一个测试。不过我想问的重点是为什么在A类的内部定义的内部类B,如果类B只有私有的构造器,为什么在A类可以直接 NEW B。
    但如果类B不是定义在类A中,那么在类A中就不能直接 NEW B ?
    OTL。。