Java中内部类和静态嵌套类的主要区别是什么?在选择其中一种时,设计/实现是否起到作用?
Java中内部类和静态嵌套类的主要区别是什么?在选择其中一种时,设计/实现是否起到作用?
我认为这里没有什么需要补充的,大多数答案已经很好地解释了静态嵌套类和内部类之间的区别。然而,当使用嵌套类与内部类时,请考虑以下问题。 正如一些答案中提到的,内部类不能在没有封闭类实例的情况下被实例化,这意味着它们持有对其封闭类实例的指针,这可能会导致内存溢出或堆栈溢出异常,因为即使封闭类不再使用,GC也无法垃圾回收它们。为了澄清这一点,请查看以下代码:
public class Outer {
public class Inner {
}
public Inner inner(){
return new Inner();
}
@Override
protected void finalize() throws Throwable {
// as you know finalize is called by the garbage collector due to destroying an object instance
System.out.println("I am destroyed !");
}
}
public static void main(String arg[]) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
// out instance is no more used and should be garbage collected !!!
// However this will not happen as inner instance is still alive i.e used, not null !
// and outer will be kept in memory until inner is destroyed
outer = null;
//
// inner = null;
//kick out garbage collector
System.gc();
}
如果你去掉对// inner = null;
的注释,程序将输出"I am destroyed !",但是如果保留这个注释它就不会输出。Outer.Inner i = new Outer.Inner();
进行实例化,上述程序也可以打印"I am destroyed !"。这些术语可以互换使用。如果您想真的严谨一点,那么您可以定义“嵌套类”是指没有封闭实例的静态内部类。在代码中,可能会像这样:
public class Outer {
public class Inner {}
public static class Nested {}
}
然而,这并不是一个被广泛接受的定义。
创建实例时,非静态内部类的实例是使用外部类对象的引用进行创建的,因为它是在定义了该内部类的外部类中创建的。这意味着它具有封闭实例。 但是,静态内部类的实例是使用外部类的引用而不是外部类对象的引用创建的。这意味着它没有封闭实例。
例如:
class A
{
class B
{
// static int x; not allowed here…..
}
static class C
{
static int x; // allowed here
}
}
class Test
{
public static void main(String… str)
{
A o=new A();
A.B obj1 =o.new B();//need of inclosing instance
A.C obj2 =new A.C();
// not need of reference of object of outer class….
}
}
嗯……内部类是嵌套类的一种形式……您是指匿名类和内部类吗?
编辑:如果您实际上是指内部类和匿名类:内部类只是在类内定义的一个类,例如:
public class A {
public class B {
}
}
…而匿名类是一个匿名定义的类的扩展,因此没有实际的“类”被定义,如下所示:
public class A {
}
A anon = new A() { /* You could change behavior of A here */ };
进一步编辑:
维基百科声称Java中有区别,但我已经使用Java工作了八年,这是我第一次听到这样的区别 - 更不用说没有引用来支持这种说法...总之,内部类是在类内定义的类(静态或非静态),而嵌套只是另一个意思,表示相同的事情。
静态和非静态嵌套类之间存在微妙的区别...基本上,非静态内部类隐式地访问封闭类的实例字段和方法(因此它们不能在静态上下文中构造,这将是编译器错误)。另一方面,静态嵌套类没有隐式访问实例字段和方法,并且可以在静态上下文中构造。
public class BankAccount {
private long accountNumber;
private String owner;
...
public static class Builder {
private long accountNumber;
private String owner;
...
static public Builder(long accountNumber) {
this.accountNumber = accountNumber;
}
public Builder withOwner(String owner){
this.owner = owner;
return this;
}
...
public BankAccount build(){
BankAccount account = new BankAccount();
account.accountNumber = this.accountNumber;
account.owner = this.owner;
...
return account;
}
}
}
内部类:内部类的常见用途是定义事件处理程序。https://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html
对于MyClass,我们使用内部类,主要因为:
内部类MyAdapter需要访问外部类成员。
在本例中,MyAdapter仅与MyClass相关联。没有其他类与MyAdapter相关,因此最好将它们组织在一起而不使用名称约定。
public class MyClass extends Applet {
...
someObject.addMouseListener(new MyAdapter());
...
class MyAdapter extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
...// Event listener implementation goes here...
...// change some outer class instance property depend on the event
}
}
}
嵌套类是一个非常通用的术语:每个不是顶级的类都是一个嵌套类。 内部类是一个非静态的嵌套类。 Joseph Darcy写了一篇非常好的关于嵌套、内部、成员和顶层类的解释。
针对初学者,包括Java和/或嵌套类的基础知识
嵌套类可以是:
1. 静态嵌套类。
2. 非静态嵌套类(也称为内部类) => 请记住这一点。
1. 内部类
例如:
class OuterClass {
/* some code here...*/
class InnerClass { }
/* some code here...*/
}
内部类是嵌套类的子集:
内部类的特点:
2.静态嵌套类:
示例:
class EnclosingClass {
static class Nested {
void someMethod() { System.out.println("hello SO"); }
}
}
class NonEnclosingClass {
public static void main(String[] args) {
/*instantiate the Nested class that is a static
member of the EnclosingClass class:
*/
EnclosingClass.Nested n = new EnclosingClass.Nested();
n.someMethod(); //prints out "hello"
}
}
class EnclosingClass {
static class Nested {
void anotherMethod() { System.out.println("hi again"); }
}
public static void main(String[] args) {
//access enclosed class:
Nested n = new Nested();
n.anotherMethod(); //prints out "hi again"
}
}
静态类的特点:
结论:
问题:在Java中,内部类和静态嵌套类之间的主要区别是什么?
答案:只需查看上面提到的每个类的具体细节即可。
public class InnerClassTest {
public static void main(String args[]) {
//creating local inner class inside method i.e. main()
class Local {
public void name() {
System.out.println("Example of Local class in Java");
}
}
//creating instance of local inner class
Local local = new Local();
local.name(); //calling method from local inner class
//Creating anonymous inner class in Java for implementing thread
Thread anonymous = new Thread(){
@Override
public void run(){
System.out.println("Anonymous class example in java");
}
};
anonymous.start();
//example of creating instance of inner class
InnerClassTest test = new InnerClassTest();
InnerClassTest.Inner inner = test.new Inner();
inner.name(); //calling method of inner class
}
//Creating Inner class in Java
private class Inner{
public void name(){
System.out.println("Inner class example in java");
}
}
}
什么是Java中的嵌套静态类?
嵌套静态类是另一个被声明为成员并被设置为静态的类。嵌套静态类也被声明为外部类的成员,可以像其他成员一样被设置为私有、公共或受保护。与内部类相比,嵌套静态类的主要优点之一是嵌套静态类的实例不附加到任何封闭实例的外部类。在Java中创建嵌套静态类的实例时,您也不需要任何外部类的实例。
1)它可以访问外部类的静态数据成员,包括私有成员。
2)静态嵌套类无法访问非静态(实例)数据成员或方法。
public class NestedStaticExample {
public static void main(String args[]){
StaticNested nested = new StaticNested();
nested.name();
}
//static nested class in java
private static class StaticNested{
public void name(){
System.out.println("static nested class example in java");
}
}
}
我认为这里的人们应该注意到,静态嵌套类只是第一个内部类。
例如:
public static class A {} //ERROR
public class A {
public class B {
public static class C {} //ERROR
}
}
public class A {
public static class B {} //COMPILE !!!
}