В чем преимущество создания внутреннего класса как статического с Java?
У меня есть внутренний класс в моем классе Java.
Когда я запускаю поиск ошибок, он рекомендует (предупреждает) сделать его статическим.
Какой смысл этого предупреждения? В чем преимущество создания внутреннего класса как статического?
5 ответов
Если вложенный класс не имеет доступа ни к одной из переменных включающего класса, его можно сделать статическим. Преимущество этого в том, что вам не нужен включающий экземпляр внешнего класса, чтобы использовать вложенный класс.
Внутренний класс по умолчанию имеет неявную ссылку на объект внешнего класса. Если вы создаете экземпляр этого объекта из кода внешнего класса, это все для вас. Если вы делаете иначе, вам нужно предоставить объект самостоятельно.
Статический внутренний класс не имеет этого.
Это означает, что его можно создать вне области внешнего объекта класса. Это также означает, что если вы "экспортируете" экземпляр внутреннего класса, это не помешает собрать текущий объект.
Как правило, если у внутреннего класса нет причин для доступа к внешнему классу, вы должны сделать его статическим по умолчанию.
Статический внутренний класс - семантически более простая вещь. Это так же, как класс верхнего уровня, за исключением того, что у вас есть больше возможностей для видимости (например, вы можете сделать его приватным).
Важной причиной, по которой следует избегать нестатических внутренних классов, является то, что они являются более сложными. Существует скрытая ссылка на внешний класс (может быть, даже больше, чем один). И простое имя в методе внутреннего класса теперь может быть одним из трех: локальное, поле или поле внешнего класса.
Артефакт такой сложности заключается в том, что скрытая ссылка на внешний класс может привести к утечкам памяти. Скажем, внутренний класс является слушателем и может быть статическим внутренним классом. Пока слушатель зарегистрирован, он содержит ссылку на экземпляр внешнего класса, который, в свою очередь, может удерживать большие объемы памяти. Создание статического состояния слушателя может позволить собирать внешний мусор.
Нестатический внутренний класс имеет неявную ссылку на внешний класс. Если вы сделаете класс статическим, вы можете сэкономить память и код.
Преимущества статических внутренних классов:
- Создание статического внутреннего класса не зависит от руководства внешнего класса и накладных расходов памяти на создание экземпляра.
- Статический внутренний класс не содержит руководства внешнего класса, не влияет на коллекцию внешнего класса, чтобы избежать расширения внешнего класса во время выживания памяти, что приведет к утечке памяти.
У нас уже есть хорошие ответы, вот мои 5 центов:
Как статические, так и нестатические внутренние классы используются, когда нам нужно разделить логические функции, используя методы и переменные внешнего класса. Оба внутренних класса имеют доступ к закрытым переменным внешнего класса.
Преимущества статического внутреннего класса: 1) статические классы могут обращаться к статическим переменным из внешнего класса 2) статические классы могут рассматриваться как независимый класс
Нестатический внутренний класс: 1) не может использовать статические члены внешнего класса 2) не может рассматриваться как независимый класс
public class NestedClassDemo {
private int a = 100;
int b = 200;
private static int c = 500;
public NestedClassDemo() {
TestInnerStatic teststat = new TestInnerStatic();
System.out.println("const of NestedClassDemo, a is:"+a+", b is:"+b+".."+teststat.teststat_a);
}
public String getTask1(){
return new TestInnerClass().getTask1();
}
public String getTask2(){
return getTask1();
}
class TestInnerClass{
int test_a = 10;
TestInnerClass() {
System.out.println("const of testinner private member of outerlcass"+a+"..."+c);
}
String getTask1(){
return "task1 from inner:"+test_a+","+a;
}
}
static class TestInnerStatic{
int teststat_a = 20;
public TestInnerStatic() {
System.out.println("const of testinnerstat:"+teststat_a+" member of outer:"+c);
}
String getTask1stat(){
return "task1 from inner stat:"+teststat_a+","+c;
}
}
public static void main(String[] args){
TestInnerStatic teststat = new TestInnerStatic();
System.out.println(teststat.teststat_a);
NestedClassDemo nestdemo = new NestedClassDemo();
System.out.println(nestdemo.getTask1()+"...."+nestdemo.getTask2());
}
}
Доступ к статическому внутреннему и нестатическому внутреннему классу извне:
public class TestClass {
public static void main(String[] args){
NestedClassDemo.TestInnerClass a = new NestedClassDemo().new TestInnerClass();
NestedClassDemo.TestInnerStatic b = new NestedClassDemo.TestInnerStatic();
}
}
Официальный документ Java для статического внутреннего класса можно найти по адресу https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html