`
explore
  • 浏览: 81011 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Java内部类可见性

    博客分类:
  • J2SE
阅读更多
转自:http://zhangjunhd.blog.51cto.com/113473/65624

在Java中,当生成一个内部类的对象时,此对象与制造它的外部类通过外部类的.this保持着联系,因此该内部类对象可以访问其外部类对象的所有成员,包括private成员。
而该内部类对象对于其他类的对象的访问,遵照常规的访问权限语法,这一点也没有什么特别支持。这里需要探讨的是,外部类以及其他类的对象可以如何访问到某个内部类对象,即内部类的可见性问题。
下面是一个示例程序Out.java,其中包含了4个不同访问权限的内部类(private,default,protected,public),在每个内部类中,分别包含4个不同访问权限的成员与方法。在外部类Out中提供了得到内部类实例的方法。
Out.java
package com.zj.main;

public class Out {
    public PrivateIn getPrivateIn(){
       return new PrivateIn();
    }
   
    public DefaultIn getDefaultIn(){
       return new DefaultIn();
    }
   
    public ProtectedIn getProtectedIn(){
       return new ProtectedIn();
    }
   
    public PublicIn getPublicIn(){
       return new PublicIn();
    }
   
    private class PrivateIn implements InMethod{
       private int private_arg;
       int default_arg;
       protected int protected_arg;
       public int public_arg;
      
       private void private_method(){};
       void default_method(){};
       protected void protected_method(){};
       public void public_method(){};
    }
   
    class DefaultIn implements InMethod{
       private int private_arg;
       int default_arg;
       protected int protected_arg;
       public int public_arg;
      
       private void private_method(){};
       void default_method(){};
       protected void protected_method(){};
       public void public_method(){};
    }
   
    protected class ProtectedIn implements InMethod{
       private int private_arg;
       int default_arg;
       protected int protected_arg;
       public int public_arg;
      
       private void private_method(){};
       void default_method(){};
       protected void protected_method(){};
       public void public_method(){};
    }
   
    public class PublicIn implements InMethod{
       private int private_arg;
       int default_arg;
       protected int protected_arg;
       public int public_arg;
      
       private void private_method(){};
       void default_method(){};
       protected void protected_method(){};
       public void public_method(){};
    }

    public static void main(String[] args){
       //create an outer object
       Out out=new Out();
      
       //create a private inner object by 'new'
       Out.PrivateIn privateIn=out.new PrivateIn();
       privateIn.private_arg=0;
       privateIn.private_method();
      
       // create a private inner object  by 'out's method'
       Out.PrivateIn privateIn2 = out.getPrivateIn();
       privateIn2.private_arg = 0;
       privateIn2.private_method();
    }
}

所有的4个内部类都实现了一个接口InMethod,该接口的作用在下文中会有讨论。下面先讨论内部类所在的外部类对其内部类对象的访问权限问题。
1.外部类的访问
我们通过两种两种方式试图创建内部类的实例。
方式一 OuterClassName.InnerClassName inner=new Ouer().new Inner();
通过外部类对象.new 的方式,可以得到private inner class 的实例,并且可以访问它的private成员和private方法。自然default、protected和public的都可以访问。

方式二 通过外部类方法get InnerInstance()
此种方法也可以访问所有内部类的所有成员和方法。
所以,一个内部类的对象对生成它的外部类对象是完全可见的,包括private内部类、private成员与private方法。
2.同包其他类的访问
下面,在同一个包内创建一个SamePackage.java类,试图访问Out类的所有内部类。
SamePackage.java
package com.zj.main;

public class SamePackage {
    public static void main(String[] args) {
       // create an outer object
       Out out = new Out();
      
       //create a private inner object by 'new'
       //Out.PrivateIn privateIn=out.new PrivateIn();
       //->error: Out.PrivateIn is not visible.

       // create a default inner object by 'new'
       Out.DefaultIn defaultIn = out.new DefaultIn();
       //defaultIn.private_arg=0;->error:not visible
       defaultIn.default_arg = 0;
       //defaultIn.private_method();->error:not visible
       defaultIn.default_method();

       // create a private inner object by 'out's method'
       //Out.PrivateIn privateIn2 = out.getPrivateIn();
       //->error:Out.PrivateIn is not visible through out.getPrivateIn() is visible.
      
       // create a private inner object by 'out's method',
       // but use Interface reference to handle it
       InMethod privateIn=out.getPrivateIn();
       privateIn.public_method();
    }
}

方式一 OuterClassName.InnerClassName inner=new Ouer().new Inner();
使用方式一试图得到private 内部类失败,根本得不到内部类的句柄。
//create a private inner object by 'new'
//Out.PrivateIn privateIn=out.new PrivateIn();
//->error: Out.PrivateIn is not visible.
    但是可以正常的访问default访问权限的内部类的对象。当然是访问不到它的private成员和private方法的。自然protected和public的都可以访问。

方式二 通过外部类方法get InnerInstance()
虽然可以调用外部类对象的getInnerInstance()方法,但由于得不到private内部类的句柄,所以此种方法无法创建private内部类的实例。
// create a private inner object by 'out's method'
//Out.PrivateIn privateIn2 = out.getPrivateIn();
//->error:Out.PrivateIn is not visible through out.getPrivateIn() is visible.
但由于所有的内部类都实现了接口InMethod。
<<interface>> InMethod.java
public interface InMethod {
    void public_method();
}

所以还是可以通过接口的引用访问到private内部类的public方法。自然default、protected和public的都可以访问这个public方法。
// create a private inner object by 'out's method',
// but use Interface reference to handle it
InMethod privateIn=out.getPrivateIn();
privateIn.public_method();
3.不同包其他类的访问
在另一个包中建立一个类DifferPackage.java。
DifferPackage.java
package com.zj.other;

import com.zj.main.InMethod;
import com.zj.main.Out;

public class DifferPackage {
    public static void main(String[] args){
       //create an outer object
       Out out=new Out();
      
       //create a public inner object by 'new'
       Out.PublicIn publicIn=out.new PublicIn();
       publicIn.public_arg=0;
       publicIn.public_method();
      
       // create a public inner object by 'out's method'
       Out.PublicIn publicIn2 = out.getPublicIn();
       publicIn2.public_arg=0;
       publicIn2.public_method();
      
       //use Interface reference
       InMethod method;
       method=out.getPrivateIn();
       method.public_method();
       method=out.getDefaultIn();
       method.public_method();
       method=out.getProtectedIn();
       method.public_method();
       method=out.getPublicIn();
       method.public_method();
    }
}

通过new方式和getInnerInstance()方法只能访问public内部类的public成员和public方法;如果使用接口的引用,则可以访问所有4个内部类的public方法。
4.不同包继承类的访问
在另一个包中建立一个类DifferPackageExtend.java,它继承自外部类Out。
DifferPackageExtend.java
package com.zj.other;

import com.zj.main.Out;

public class DifferPackageAndExtend extends Out{
    public static void main(String[] args){
       //create an DifferPackageAndExtend's object,which extends Out
       Out extend=new DifferPackageAndExtend();
      
       //create a protected inner object by 'new'
       //Out.ProtectedIn protectedIn=extend.new ProtectedIn();
       //->error:The constructor Out.ProtectedIn() is not visible
      
       // create a protected inner object by 'out's method'
       Out.ProtectedIn protectedIn=extend.getProtectedIn();
       protectedIn.public_arg=0;
       protectedIn.public_method();
    }
}

通过new方式,虽然可以得到内部类的句柄Out.ProtectedIn,但该内部类的构造子却不可见。
通过getInnerInstance()方法得到protected内部类的对象,但只能访问到public成员和public方法。由此可知,protected内部类并不关心是否有其他类继承自它的外部类。所有protected访问权限不在此种情况下适用。
分享到:
评论

相关推荐

    浅谈Java内部类的四个应用场景

    ### Java内部类的应用场景 ...通过这种方式,我们不仅能够有效地管理数据库连接,还能够利用Java内部类的特性来增强代码的结构和安全性。这种模式适用于任何需要紧密耦合并且对外部不可见的类场景。

    探讨Java内部类的可见性

    这里需要探讨的是,外部类以及其他类的对象可以如何访问到某个内部类对象,即内部类的可见性问题。  下面是一个示例程序Out.java,其中包含了4个不同访问权限的内部类(private,default,protected,public),...

    Java内部类总结

    ### Java内部类详解 #### 一、什么是内部类? 内部类,顾名思义,是在另一个类的内部定义的类。这种独特的结构让内部类能够访问包含它的外部类的私有成员,包括变量和方法。这为编程提供了一种封装更紧密、功能更...

    java内部类使用总结

    Java内部类是Java语言中一个独特且强大的特性,它允许我们在一个类的内部定义另一个类。内部类提供了增强封装的能力,使得内部类可以被隐藏在外部类中,仅对外部类可见,从而增加了代码的隐私性和安全性。同时,内部...

    java静态内部类(嵌套类)

    4. **访问修饰符**:静态内部类可以被声明为`public`、`protected`或`private`等访问修饰符,这使得我们可以根据需要控制其可见性。 5. **静态方法调用**:在静态内部类中可以直接访问外部类的静态方法和变量,但是...

    java 集合和内部类资料

    根据其可见性和位置,内部类可以分为以下几类: 1. 成员内部类:在类的主体中定义,与类的其他成员具有相同的权限。 2. 局部内部类:在方法、构造器或块中定义,仅在其定义范围内可见。 3. 匿名内部类:没有名字的...

    java内部类应用详解

    总之,Java内部类提供了一种灵活的方式来组织和管理代码,增加了代码的复用性和可读性,同时也让设计模式如策略模式、装饰器模式等在Java中得以轻松实现。理解并熟练运用内部类是提升Java编程能力的关键步骤之一。

    java内部类1

    总结来说,Java内部类提供了一种强大的工具,使得我们可以更灵活地组织代码,增强封装性和模块化。非静态内部类与静态内部类在依赖关系、创建方式和访问权限上有所不同,可以根据具体需求选择使用。局部内部类则适用...

    关于Java变量的可见性问题Java开发Java经验技巧共

    在Java编程语言中,变量的可见性是一个至关重要的概念,它直接影响着代码的组织和运行。本主题将深入探讨Java中的变量可见性,包括其基本原理、规则以及如何有效地利用这些规则来优化代码。 首先,Java变量有四种...

    Java内部类总结.pdf

    Java内部类是Java语言中一个独特且强大的特性,它允许在一个类的定义内部定义另一个类。内部类在Java中主要用于创建更加紧密耦合的对象,尤其是在处理事件处理和封装时。虽然在J2EE编程中使用不多,但在GUI编程中...

    Java内部类.pdf

    ### Java内部类详解 #### 一、定义及意义 **定义**:内部类是指在一个类的...综上所述,Java内部类为Java编程提供了强大的灵活性和封装性,理解并合理运用内部类的概念,可以帮助开发者写出更加高效、优雅的代码。

    java内部类总结.pdf

    Java内部类是Java语言的一个独特特性,它允许一个类被定义在另一个类的内部。这种设计使得代码结构更加紧凑,同时也提供了对封装和抽象的新层次。内部类在J2EE编程中可能用得较少,但在GUI编程中尤其常见,主要用于...

    JAVA内部类

    ### JAVA内部类详解 #### 引言 自Java1.1版本起,内部类的引入为面向对象编程提供了更为灵活的封装机制。然而,如同所有强大的特性,内部类的不当使用可能导致代码复杂度的增加,甚至产生维护上的困难。本文旨在...

    讲解Java中如何构造内部类对象以及访问对象

    在Java编程语言中,内部类(也称为嵌套类)是一种特殊类型的类,它可以被定义在一个外部类的内部。内部类有四种类型:成员内部类、局部内部类、匿名内部类和静态内部类。本篇将主要讨论如何构造内部类对象以及如何...

    内部类 匿名内部类 内部接口 对比说明

    内部类是Java编程语言中的一种特性,它允许我们在一个类的内部定义另一个类。这种设计模式在Android开发中尤其常见,因为它可以有效地管理代码和实现特定的功能。本文将详细探讨内部类、匿名内部类以及内部接口的...

    详细介绍java中的内部类共8页.pdf.zip

    以下是关于Java内部类的详细知识: 1. **类型划分**: - 成员内部类:定义在类的成员位置,可以访问外部类的所有成员,包括私有成员。 - 局部内部类:定义在方法或作用域内,仅在这个方法或作用域可见。 - 匿名...

    Java基础权限控制与final,内部类

    final关键字用于限制类、方法或变量的可变性,而权限控制则决定了类成员的可见性和可用范围。内部类则为类的设计提供了更多的灵活性,允许在类的内部实现更复杂的结构。理解这些概念对于编写高效、可维护的Java代码...

    几行代码带你彻底搞懂Java内部类

    Java内部类是Java语言的一个独特特性,它允许一个类被定义在另一个类的内部。这种设计模式提供了很多灵活性,比如可以更容易地访问外部类的私有成员,实现更复杂的抽象,以及在某些情况下模拟多重继承。以下是关于...

    Java 中包的概念,类的说明符与内部类19

    在Java中,类的说明符包括访问修饰符、静态修饰符、最终修饰符(final)、抽象修饰符(abstract)等,这些修饰符用来控制类的可见性和行为。例如,访问修饰符如public、private、protected以及默认(无修饰符),...

    JAVA类的特性资料

    11. **内部类**:Java支持类的嵌套,内部类可以作为外部类的成员,有成员内部类、局部内部类、匿名内部类和静态内部类等。内部类可以访问外部类的私有成员,增加了代码的复杂性和灵活性。 12. **包(package)**:...

Global site tag (gtag.js) - Google Analytics