Java 私有类的公共构造函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23180476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 21:12:34  来源:igfitidea点击:

Public constructor of a private class

javaconstructor

提问by Mick

I am new to Java. I want to know what it is the use of publicconstructor in a privateclass. Private class inside the class can be initialized from the same class then what it is the use to make the constructor of private class to public?

我是 Java 新手。我想知道在私有类中使用公共构造函数是什么。类内部的私有类可以从同一个类中初始化,那么私有类的构造函数为public有什么用呢?

public class MainActivity extends Activity {
     private class AcceptThread extends Thread {
        public AcceptThread() {

        }
    }
}

采纳答案by kapex

There doesn't seems to be any real use case for public or protected modifiers with private classes. If you have multiple classes in a single file though (but not nested or local), you need non-private constructors to instantiate the private classes.

对于具有私有类的 public 或 protected 修饰符,似乎没有任何真正的用例。如果单个文件中有多个类(但不是嵌套的或本地的),则需要非私有构造函数来实例化私有类。

// X.java

public class X {
    private Y y = new Y();
}

class Y {
    Y () {
        // if this were private, X wouldn't be able to create an instance of Y
    }
}

Actually defaultor protectedvisibility would be enough to create an instance in this case. All non-private modifiers allow you to create instances from other classes within the same package but practically have the same visibility.

在这种情况下,实际上默认protected可见性足以创建一个实例。所有非私有修饰符都允许您从同一包内的其他类创建实例,但实际上具有相同的可见性。

  • The private class isn't visible to classes outside of the package, so publicmethods have no use here.
  • The private class can't be extended by classes outside of the package, so protectedhas no use either.
  • Even when using reflections, a public constructor is not accessible by default from other packages and will throw a IllegalAccessException. It checks the class visibility first, then the member visibility.
  • 私有类对包外的类不可见,因此public方法在这里没有用。
  • 私有类不能被包外的类扩展,所以protected也没有用。
  • 即使使用反射,默认情况下也无法从其他包访问公共构造函数,并且会抛出IllegalAccessException. 它首先检查类的可见性,然后是成员的可见性。

The defaultmodifier is the most restrictive modifier that allows you to directly call the constructor from other classes, so package-private seems to be the most appropriate visibility for the constructor and also any other non-private methods. This also has the advantage that if you change the class visibility in the future, you don't accidentally expose the constructor or any methods to the public.

默认修饰符是最严格的修改,允许你直接调用其他类的构造函数,所以包私人似乎是构造最合适的知名度以及任何其他非私有方法。这样做的另一个好处是,如果您将来更改类的可见性,就不会意外地将构造函数或任何方法公开给公众。

回答by JvR

You know, I ask myself this question almost each time I make a private inner class, but I always assumed that there could be some (possibly contrived) reason for a public constructor. So @kapep 's answer got me tingling and encouraged to find ways to require a public constructor on a private inner class, but the more I think and experiment with it, the more I think the holes are plugged.

你知道,几乎每次我创建一个私有内部类时我都会问自己这个问题,但我总是假设公共构造函数可能有一些(可能是人为的)原因。所以@kapep 的回答让我感到刺痛,并鼓励我找到在私有内部类上需要公共构造函数的方法,但是我越想和试验它,我就越认为这些漏洞被堵塞了。

Possible angles, all of which failed me:

可能的角度,所有这些都让我失望:

  • Serialisation: When unmarshalling an object whose superclass is not serializable, the superclass needs a no-arg constructor accessible from the subclass. So, protectedshould always suffice here.

  • Reflective tools: Code that uses reflection to get the inner class constructor through a returned instance. Fails because the type visibility is checked first, as @kapep pointed out, though it leaves a rather interesting error message:

    Exception in thread "main" java.lang.IllegalAccessException: Class A can not access a member of class contrived.B$C with modifiers "public"

  • Inner class extension shenanigans: Don't try this at home:

    package a;
    class Outer {
      private class Inner {
      }
    }
    
    package b;
    // compile error: Outer.Inner has private access in Outer
    class Extender extends a.Outer.Inner {
      Extender(a.Outer outer) {
        outer.super();
      }
    }
    

    Seemed promising at first, but I didn't get too far with that one.

  • 序列化:当解组其超类不可序列化的对象时,超类需要一个可从子类访问的无参数构造函数。所以,protected在这里应该总是足够的。

  • 反射工具:使用反射通过返回的实例获取内部类构造函数的代码。失败,因为首先检查类型可见性,正如@kapep 指出的那样,尽管它留下了一个相当有趣的错误消息:

    线程“main”中的异常java.lang.IllegalAccessException:类A无法访问带有修饰符“public”的类contrived.B$C的成员

  • 内部类扩展恶作剧:不要在家里尝试这个:

    package a;
    class Outer {
      private class Inner {
      }
    }
    
    package b;
    // compile error: Outer.Inner has private access in Outer
    class Extender extends a.Outer.Inner {
      Extender(a.Outer outer) {
        outer.super();
      }
    }
    

    一开始看起来很有希望,但我并没有走得太远。



In the end, I could not find a way to make a public constructor on a private inner class useful.

最后,我找不到让私有内部类上的公共构造函数有用的方法

Then why is this technically legal despite having no use? Probably because the compiler automagically inserts a no-arg public constructor when no other constructor is provided. Hence the language should not disallow this constructs. More of an artefact than a reason, though.

那么为什么这在技术上是合法的,尽管没有用?可能是因为当没有提供其他构造函数时,编译器会自动插入一个无参数的公共构造函数。因此,语言不应禁止这种结构。不过,与其说是原因,不如说是一种人工制品。