java Java中常用内部类吗?他们是“坏人”吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1028850/
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
Are inner classes commonly used in Java? Are they "bad"?
提问by johnny
Are inner classes commonly used in Java? Are these the same as nested classes? Or have these been replaced in Java by something better? I have a book on version 5 and it has an example using an inner class, but I thought I read somewere that inner classes were "bad."
Java中常用内部类吗?这些与嵌套类相同吗?或者这些在 Java 中被更好的东西取代了?我有一本关于第 5 版的书,它有一个使用内部类的例子,但我认为我读过一些内部类是“坏的”。
I have no idea and was hoping for thoughts on it.
我不知道,并希望对此有想法。
Thank you.
谢谢你。
回答by Daniel Earwicker
Inner classes are frequently used, and something very similar - anonymous classes - are practically indispensable, as they are the closest thing Java has to closures. So if you can't remember where you heard that inner classes are bad, try to forget about it!
内部类经常使用,非常相似的东西——匿名类——实际上是必不可少的,因为它们是 Java 最接近闭包的东西。所以如果你不记得你在哪里听说内部类不好,试着忘记它!
回答by Brian Agnew
They're not "bad" as such.
他们并不像这样“坏”。
They can be subject to abuse (inner classes of inner classes, for example). As soon as my inner class spans more than a few lines, I prefer to extract it into its own class. It aids readability, and testing in some instances.
它们可能会受到滥用(例如,内部类的内部类)。一旦我的内部类跨越几行,我更喜欢将它提取到它自己的类中。它有助于可读性,并在某些情况下进行测试。
There's one gotcha which isn't immediately obvious, and worth remembering. Any non-staticinner class will have an implicit reference to the surrounding outer class (an implicit 'this ' reference). This isn't normally an issue, but if you come to serialise the inner class (say, using XStream), you'll find that this can cause you unexpected grief.
有一个问题不是很明显,值得记住。任何非static内部类都将隐式引用周围的外部类(隐式“this”引用)。这通常不是问题,但是如果您要序列化内部类(例如,使用XStream),您会发现这可能会给您带来意想不到的痛苦。
回答by Tom
I don't think they are evil or bad. Maybe they are not widely used, but they do have many uses,callbacks being one of them. A special advantage is that they can extend from a different class than the outer class, so you could have multiple inheritance.
我不认为他们是邪恶的或坏的。也许它们没有被广泛使用,但它们确实有很多用途,回调就是其中之一。一个特殊的优点是它们可以从与外部类不同的类进行扩展,因此您可以进行多重继承。
I would say that one of the issues with inner classes is that their syntax is somewhat "ugly". That's something that discourages some people. Here at work there are many of them.
我会说内部类的问题之一是它们的语法有点“丑陋”。这是让一些人气馁的事情。在工作中,有很多这样的人。
回答by Jherico
A good example of an inner class is the iterator implementation for a given collection type. Its a class that implements a public interface, but has no business existing except in association with another class. It allows you to model things that in C++ you would be forced to do with the friend operator.
内部类的一个很好的例子是给定集合类型的迭代器实现。它是一个实现公共接口的类,但除了与另一个类关联外,没有任何业务存在。它允许您对在 C++ 中必须使用友元运算符进行的事情进行建模。
回答by quant_dev
Non-static inner classes can hide a performance problem. They do have access to member fields on the enclosing class, but not directly, but via getters which are created automatically. This will be slower then just copying the members of the enclosing class to the inner class.
非静态内部类可以隐藏性能问题。他们确实可以访问封闭类上的成员字段,但不能直接访问,而是通过自动创建的 getter 访问。这将比将封闭类的成员复制到内部类要慢。
Some other problems with non-static inner classes are described here
此处描述了非静态内部类的一些其他问题
回答by Paul Sonier
They are useful and can be very commonly used. While you should be cautious about abusing the functionality, they aren't much more liable to be abused than any other language feature.
它们很有用并且可以非常常用。虽然您应该谨慎滥用该功能,但它们并不比任何其他语言功能更容易被滥用。
回答by Toddy Zed
The key thing to remember is that you are going to trade flexibility for simplicity and cohesion by making the two classes more tightly coupled. You may want the classes to be tightly bound, but you are giving up the ability to transparently swap other classes into the place of what is currently your embedded class by not defining your class from an interface outside of the containing class.
要记住的关键是,您将通过使两个类更紧密地耦合来交换灵活性以换取简单性和内聚性。您可能希望这些类紧密绑定,但是您放弃了通过不从包含类之外的接口定义您的类来透明地将其他类交换到当前嵌入类的位置的能力。
回答by Gagandeep Singh
Consider following example :
考虑以下示例:
public class OuterClass {
private AnonymousInnerClass anonymousInnerClass = new AnonymousInnerClass() {
@Override
protected void printAboutme() {
System.out.println("AnonymousInnerClass.printAboutMe.........");
Class clazz = this.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String message = Modifier.isPublic(field.getModifiers()) ? "public":(Modifier.isPrivate(field.getModifiers())?"private":"protected");
message = message + " " + field.getType().getSimpleName();
message = message + " " + field.getName();
System.out.println(message);
}
}
};
public void displayAnonymousInnerClass() {
anonymousInnerClass.printAboutme();
}
public void displayStaticInnerClass() {
NestedStaticClass staticInnerClass = new NestedStaticClass();
staticInnerClass.printAboutMe();
}
public void displayInnerClass() {
InnerClass innerClass = new InnerClass();
innerClass.printAboutMe();
}
public void displayMethodInnerClass(){
class MethodInnerClass {
private String sampleField = "Method Inner Class";
public void printAboutMe() {
System.out.println("MethodInnerClass.printAboutMe.........");
Class clazz = this.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String message = Modifier.isPublic(field.getModifiers()) ? "public":(Modifier.isPrivate(field.getModifiers())?"private":"protected");
message = message + " " + field.getType().getSimpleName();
message = message + " " + field.getName();
System.out.println(message);
}
}
}
MethodInnerClass methodInnerClass = new MethodInnerClass();
methodInnerClass.printAboutMe();
}
class InnerClass {
private String sampleField = "Inner Class";
public void printAboutMe() {
System.out.println("InnerClass.printAboutMe.........");
Class clazz = this.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String message = Modifier.isPublic(field.getModifiers()) ? "public":(Modifier.isPrivate(field.getModifiers())?"private":"protected");
message = message + " " + field.getType().getSimpleName();
message = message + " " + field.getName();
System.out.println(message);
}
}
}
abstract class AnonymousInnerClass {
protected String sampleField = "Anonymous Inner Class";
protected abstract void printAboutme();
}
static class NestedStaticClass {
private String sampleField = "NestedStaticClass";
public void printAboutMe() {
System.out.println("NestedStaticClass.printAboutMe.........");
Class clazz = this.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String message = Modifier.isPublic(field.getModifiers()) ? "public":(Modifier.isPrivate(field.getModifiers())?"private":"protected");
message = message + " " + field.getType().getSimpleName();
message = message + " " + field.getName();
System.out.println(message);
}
}
}
}
}
in this example there is comparison of every type of non static nested class with static nested class.Now if you run display method of Outer class for each nested class you will see output of each nested class printAboutMe() method,which has some reflection code to print all the member variables of nested classes.
在此示例中,将每种类型的非静态嵌套类与静态嵌套类进行比较。现在,如果您为每个嵌套类运行 Outer 类的 display 方法,您将看到每个嵌套类的 printAboutMe() 方法的输出,其中包含一些反射代码打印嵌套类的所有成员变量。
You will see for non nested classes there is one extra member variable other than declared variable string in code,which is only present at run time.
您将看到对于非嵌套类,除了代码中声明的变量字符串之外,还有一个额外的成员变量,它仅在运行时出现。
for instance if we execute following code for InnerClass. :-
例如,如果我们为 InnerClass 执行以下代码。:-
public class NestedClassesDemo {
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
outerClass.displayInnerClass();
}
}
}
output is like this :-
输出是这样的:-
InnerClass.printAboutMe.........
private String sampleField
protected OuterClass this##代码##
Note there is mystery member variable this$0 of type enclosing class(Outer class).
请注意,存在封闭类(外部类)类型的神秘成员变量 this$0。
Now you are clear that inner classes keep reference to outer class.So image scenario where you pass reference of inner class to other outer world class and then reference never gets released to in turn OuterClass is also referenced , hence leak.
现在你很清楚内部类保持对外部类的引用。所以图像场景,你将内部类的引用传递给其他外部世界类,然后引用永远不会被释放到反过来 OuterClass 也被引用,因此泄漏。
So this makes using inner classes bad if not used prpperly.
因此,如果不正确使用,这会使使用内部类变得糟糕。
There not such case with static inner classes.Please run all display methods.Also if any problem in code please do point out.
静态内部类没有这种情况。请运行所有显示方法。如果代码中有任何问题,请指出。

