Java

Java 知识量:11 - 45 - 220

4.5 嵌套类型><

嵌套类型简介- 4.5.1 -

在Java中,嵌套类型(内部类)是一个定义在其他类中的类。内部类可以访问外部类的私有属性和方法,因此它们可以非常有用。

Java支持两种类型的内部类:

1、非静态内部类(或称为嵌套类):这种内部类依赖于外部类的实例。只有创建了外部类的实例后,才能创建非静态内部类的实例。非静态内部类可以访问外部类的实例变量和非静态方法。例如:

public class OuterClass {  
    private int data = 10;  
    class InnerClass {  
        void message() {  
            System.out.println("Data is " + data);  
        }  
    }  
}

在上述例子中,InnerClass 是一个非静态内部类。它可以访问 OuterClass 的私有变量 data。
2、 静态内部类:这种内部类不依赖于外部类的实例,它可以像普通的类一样独立存在。静态内部类只能访问外部类的静态变量和静态方法。例如:

public class OuterClass {  
    private static int data = 10;  
    static class InnerClass {  
        void message() {  
            System.out.println("Data is " + data);  
        }  
    }  
}

在上述例子中,InnerClass 是一个静态内部类。它可以访问 OuterClass 的静态变量 data。

创建内部类的语法如下:

OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();

对于静态内部类,语法如下:

OuterClass.InnerClass innerObject = new OuterClass.InnerClass();

静态成员类型- 4.5.2 -

在Java中,静态成员是属于类的一部分,而不是类的实例。它们可以在不创建类的实例的情况下进行访问。静态成员可以是任何类型,包括基本数据类型,对象类型,数组类型,类类型,接口类型等。

以下是一个定义和使用静态成员接口的示例:

// 定义一个静态成员接口  
public interface MyInterface {  
    static void myStaticMethod() {  
        System.out.println("这是一个静态方法");  
    }  
  
    static int myStaticVar = 10;  
}  
  
// 使用静态成员接口  
public class MyClass implements MyInterface {  
    public static void main(String[] args) {  
        // 调用静态方法  
        MyInterface.myStaticMethod();  
  
        // 访问静态变量  
        System.out.println(MyInterface.myStaticVar);  
    }  
}

在这个示例中,定义了一个名为MyInterface的静态成员接口,并在其中定义了一个静态方法myStaticMethod和一个静态变量myStaticVar。然后,创建了一个实现了MyInterface接口的类MyClass,并在其中调用了静态方法和访问了静态变量。

注意:在实现静态成员接口时,不需要实现其中的静态方法和变量,因为它们是与接口本身关联的,而不是与实现类关联的。

以下是Java静态成员的一些主要特性:

  • 静态成员不属于任何一个特定的类实例,而是属于整个类。换句话说,类的所有实例共享同一个静态成员。

  • 静态成员在类加载时自动创建和初始化,或者执行相关代码,因此它们不需要在每个实例中都进行创建和初始化。

  • 对于一个给定的类,其静态成员只会有一个实例。即使类有多个实例,这些实例都会共享同一个静态成员。

  • 静态成员可以用来保存和操作在多个实例之间共享的数据,例如单例模式下的引用保存。

  • 静态方法可以像普通方法一样被类实例访问,也可以直接通过类名来访问。

  • 静态代码块在类加载时执行,并且可以使用静态成员变量和方法。

  • 静态成员不保存在任意一个对象的内存空间中,而是保存在类的公共区域中。所以任何一个对象都可以直接访问该类的静态成员,都能获得相同的数据值。

  • 当修改静态成员时,改动会在类的公共区域进行,影响所有类的实例。

非静态成员类- 4.5.3 -

非静态成员类是Java中的一种成员类,它们必须依赖于外部类的对象而存在,不能单独存在。在非静态成员类中,可以定义静态成员方法和非静态成员方法,但是不能定义静态成员变量。

非静态成员类的作用主要在于与外部类进行交互和操作,可以通过外部类的实例访问非静态成员类中的方法和变量。

注意:在非静态成员类中不能定义静态成员变量,因为静态成员变量属于类本身,而非静态成员变量属于类的实例。同时,非静态成员类实例的生命周期与外部实例的生命周期相同,它们在外部实例被销毁时也会被销毁。

以下是一个简单的例子,说明如何在Java中通过成员类实现迭代器:

import java.util.Iterator;  
  
public class MyContainer {  
    private int[] elements;  
    private int size;  
    private int index;  
  
    public MyContainer(int[] elements) {  
        this.elements = elements;  
        this.size = elements.length;  
        this.index = 0;  
    }  
  
    public class MyIterator implements Iterator<Integer> {  
        @Override  
        public boolean hasNext() {  
            return index < size;  
        }  
  
        @Override  
        public Integer next() {  
            if (!hasNext()) {  
                throw new IllegalStateException("Container has been exhausted");  
            }  
            return elements[index++];  
        }  
    }  
  
    public Iterator<Integer> getIterator() {  
        return new MyIterator();  
    }  
}

在这个例子中,MyContainer类有一个成员类MyIterator,它实现了Iterator<Integer>接口。MyIterator类中的hasNext()和next()方法允许遍历MyContainer中的元素。可以使用getIterator()方法来获取一个新的迭代器实例,然后使用这个迭代器来遍历容器中的元素。

局部类- 4.5.4 -

Java局部类(也称为嵌套类)是在一个类的内部定义的另一个类。它们可以分为静态局部类和非静态局部类两种类型。

  • 静态局部类:静态局部类是在一个类的内部定义的另一个静态类。它们可以像普通的静态类一样使用,但不能访问外部类的实例变量。静态局部类可以像普通的静态类一样使用,但不能访问外部类的实例变量。

  • 非静态局部类:非静态局部类是在一个类的内部定义的另一个非静态类。它们可以访问外部类的实例变量和方法,并且可以被声明为private、protected或public。非静态局部类可以像普通的类一样使用,但只能在定义它们的块或方法中访问。

以下是Java局部类的示例:

public class OuterClass {  
    private int outerVariable = 10;  
      
    public void outerMethod() {  
        class LocalClass {  
            private int localVariable = 5;  
              
            public void localMethod() {  
                System.out.println("Local variable: " + localVariable);  
                System.out.println("Outer variable: " + outerVariable);  
            }  
        }  
          
        LocalClass localObject = new LocalClass();  
        localObject.localMethod();  
    }  
      
    public static void main(String[] args) {  
        OuterClass outerObject = new OuterClass();  
        outerObject.outerMethod();  
    }  
}

在这个示例中,LocalClass是一个非静态局部类,它可以访问外部类的实例变量outerVariable。在outerMethod()方法中,创建了一个LocalClass的实例localObject,并调用了它的localMethod()方法。在localMethod()方法中,打印了localVariable和outerVariable的值。最后,在main()方法中,创建了一个OuterClass的实例outerObject,并调用了它的outerMethod()方法。

匿名类- 4.5.5 -

匿名类是一种没有名称的类,它是在代码中直接定义和使用的。匿名类通常用于创建一个对象,而这个对象的生命周期只在创建它的方法或代码块中。

在Java中,匿名类通常用于以下情况:

1、实现接口:当一个类需要实现一个接口,但是这个类只需要实现接口中的一个或几个方法时,可以使用匿名类。

例如,假设有一个名为Runnable的接口,它只有一个方法void run()。要创建一个实现该接口的类,可以使用以下代码:

Runnable runnable = new Runnable() {  
    public void run() {  
        // 实现run方法的代码  
    }  
};

2、继承类:当一个类需要继承另一个类,但是这个类只需要重写父类中的一个或几个方法时,可以使用匿名类。

例如,假设有一个名为Thread的类,它有一个方法void run()。要创建一个继承Thread类的类,可以使用以下代码:

Thread thread = new Thread() {  
    public void run() {  
        // 实现run方法的代码  
    }  
};

3、作为参数传递:在某些情况下,需要将一个对象作为参数传递给一个方法,而这个对象只需要在方法中使用一次。这时可以使用匿名类来创建这个对象。

例如,假设有一个名为sort的方法,它接受一个Comparator对象作为参数。要创建一个Comparator对象,可以使用以下代码:

Collections.sort(list, new Comparator<String>() {  
    public int compare(String s1, String s2) {  
        return s1.compareTo(s2);  
    }  
});

注意:匿名类不能定义构造函数,因为它没有名称。此外,匿名类中只能定义final变量。