Также, как вы знаете, в Java существуют вложенные классы, которые являются статическими внутренними объектами.
Из предыдущих постов становится ясно, когда нам нужно использовать внутренний класс, но я думаю, что вас также интересует вопрос "Почему мынужны вложенные классы (статический внутренний класс) ".
Ответ прост: есть та же цель, что и для внутреннего класса, за исключением нескольких вещей.
1) Вложенный класс (static inner) требуется, когда мы хотим исключить некоторую логику, котораякасается другого объекта, но эта логика может использоваться во внешнем мире.
Простейшие примеры - это построители или редакторы какого-либо объекта.Например, у нас есть класс Foo, в котором может быть много необязательных полей, для создания такого объекта мы можем решить ввести класс построителя, который будет выполнять эту работу.
public class Foo {
private int param1;
private int param2;
private int param3;
private Foo(FooBuilder builder) {
this.param1 = builder.param1;
this.param2 = builder.param2;
this.param3 = builder.param3;
}
public int getParam1() {
return param1;
}
public void setParam1(int param1) {
this.param1 = param1;
}
public int getParam2() {
return param2;
}
public void setParam2(int param2) {
this.param2 = param2;
}
public int getParam3() {
return param3;
}
public void setParam3(int param3) {
this.param3 = param3;
}
public static class FooBuilder {
private int param1;
private int param2;
private int param3;
public FooBuilder() {
}
public FooBuilder withParameter1(int param1) {
this.param1 = param1;
return this;
}
public FooBuilder withParameter2(int param2) {
this.param2 = param2;
return this;
}
public FooBuilder withParameter3(int param3) {
this.param3 = param3;
return this;
}
public Foo build() {
return new Foo(this);
}
}
}
Этот пример иллюстрирует, по крайней мере, одну причину, почемунам нужны такие классы
2) Второе различие между внутренним и статическим внутренними классами состоит в том, что у первого всегда есть указатель на родительский класс.На самом деле компилятор создает синтетический элемент поля для нестатического внутреннего класса типа его родителя, именно поэтому мы можем получить доступ к закрытым членам родительского класса.Статическое внутреннее условие не имеет такого сгенерированного члена поля.Например, у нас есть просто простой родительский класс с объявленным нестатическим внутренним классом:
public class Foo {
public class FooBuilder {
}
}
, но на самом деле, если принять во внимание байт-код, он выглядит так:
public class Foo {
public class FooBuilder {
private Foo generatedNameHere;
}
}
, если вы хотитеВы можете выяснить этот сгенерированный байтовый код.