黑马程序员技术交流社区

标题: 关于对静态内部类中私有成员的访问??? [打印本页]

作者: 王志明    时间: 2012-7-31 20:16
标题: 关于对静态内部类中私有成员的访问???
本帖最后由 王志明 于 2012-8-1 03:34 编辑

首先谢谢各位同学的帮助,我又思考了下,得出了以下结论,有不妥的地方希望大家指点
内部类方位外部类成员(包括实例成员和静态成员)时,可以直接访问,因为内部类持有外部类实例的引用,格式为 外部类名.this
外部类访问内部类实例成员(内部类只能有实例成员)时,内部类的成员不管哪种访问级别对于外部类都是可以访问的,需要创建内部类实例
内部类访问内部类成员(实例成员)时,因为内部类实例是建立在外部类实例的基础上的,内部类对内部类的访问都要通过外部类来实现,内部类的成员不管哪种访问级别对于外部类都是可以访问的,所以类中的内部类与内部类之间可以互相访问而不受权限的控制
内部类(包括局部内部类,不包括静态内部类)中不能有静态成员,因为内部类是建立在外部类的实例上的,只有创建了外部类的实例后,内部类才会被加载,外部类的实例还没创建的时候,内部类中的静态方法能被加载吗?
静态内部类不不能直接访问外部类的实例成员,因为静态内部类的加载不依赖外部类的实例,当外部类加载完毕时,静态内部类也被加载了,在静态内部类中没有对外部类实例的引用,所以要访问外部类的实例成员时,需要使用外部类实例来引用,基于静态内部类随外部类一起加载的原理,静态内部类是可以直接访问外部类静态成员的,也可以定义静态成员
总结:内部类是在外部类创建实例后被加载的,静态内部类是随着外部类一起被加载的

下面是原先的问题
做了个对静态内部类私有成员的访问测试,发现如果不出外部类的范围,就可以访问静态内部类的私有成员,有点不解?求指点。。
public class TestInner {
        public static void main(String[] args) {
                // 这里为什么能访问Inner1的私有构造器
                Inner inner1 = new Inner1();

                // 还能访问Inner1的私有成员变量
                System.out.println(inner1.num);
        }

        public static class Inner1 {
                //私有的
                private int num = 5;
               
                //私有的
                private Inner1() {
                }
               
                //私有的
                private void test() {
                        System.out.println("test");
                }
        }

        public static class Inner2 {
                public Inner2() {
                        // 这里为什么能访问Inner1的私有构造器和私有方法
                        Inner1 inner1 = new Inner1();
                        inner1.test();
                        // 还能访问Inner1的私有成员变量
                        System.out.println(inner1.num);
                }
        }
}



作者: 马州州    时间: 2012-7-31 20:47
本帖最后由 马州州 于 2012-7-31 20:50 编辑

public class TestInner {

        public static void main(String[] args) {
                // 这里为什么能访问Inner1的私有构造器和私有方法
                Inner1 inner1 = new Inner1();
                inner1.test();
                // 还能访问Inner1的私有成员变量
                System.out.println(inner1.num);

        }

        public static class Inner1 {
                //私有的
                private int num = 5;
               
                //私有的
                private Inner1() {
                }
               
                //私有的
                private void test() {
                        System.out.println("test");
                }
        }

        public static class Inner2 {
                public Inner2() {
                        // 这里为什么能访问Inner1的私有构造器和私有方法
                        Inner1 inner1 = new Inner1();
                        inner1.test();
                        // 还能访问Inner1的私有成员变量
                        System.out.println(inner1.num);
                }
        }
}
楼主看红色的static,你把类修饰成静态的,毕老师在视频中讲过,静态是可以直接调用静态的,如果你修饰类的static去掉,就不能引用了


老毕主要讲的是静态在类中的修饰作用,静态直接修饰类的话这个类中的变量,方法都是可以直接被调用的,因为随着类的加载都已经加载进方法区了
因为你用静态去修饰,就算私有了也是在方法区里面被共享的

附上老毕讲的static的知识点
static特点:
1,随着类的加载而加载。
   也就说:静态会随着类的消失而消失。说明它的生命周期最长。
2,优先于的对象存在
明确一点:静态是先存在。对象是后存在的。
3,被所有对象所共享
4,可以直接被类名所调用。
实例变量和类变量的区别:
1,存放位置。
类变量随着类的加载而存在于方法区中。
实例变量随着对象的建立而存在于堆内存中。
2,生命周期:
类变量生命周期最长,随着类的消失而消失。
实例变量生命周期随着对象的消失而消失。

静态使用注意事项:
1,静态方法只能访问静态成员。
非静态方法既可以访问静态也可以访问非静态。
2,静态方法中不可以定义this,super关键字。
因为静态优先于对象存在。所以静态方法中不可以出现this。
3,主函数是静态的。




作者: 朱烈葵    时间: 2012-7-31 20:52
问题是static的作用,static修饰的类,是随着类的加载而加载,就是说你要new对象,必须先加载.class 文件对象是吗?在你加载的时候static类就先存在了,所以能访问了,答的不好,不过就是这个意思
作者: 周坤    时间: 2012-7-31 20:55
自然能访问了,因为new出了本内部类的实例对象,等于自己的类访问自己的私有成员。
public static void main(String[] args) {
                // 这里为什么能访问Inner1的私有构造器和私有方法??这里是inner1在访问,它指向的是Inner1()的对象,所以是自己访问自己。

                Inner1 inner1 = new Inner1();
                inner1.test();

                // 还能访问Inner1的私有成员变量

                System.out.println(inner1.num);
        }


作者: 王志明    时间: 2012-7-31 20:59
马州州 发表于 2012-7-31 20:47
public class TestInner {
        public static void main(String[] args) {                // 这里为什 ...

将Inner1改成非静态也可以访问

作者: 周坤    时间: 2012-7-31 21:05
王志明 发表于 2012-7-31 20:59
将Inner1改成非静态也可以访问

非静态类的话,只能这样创建对象
Inner1 inner1 = new Test6_extends(). new Inner1();
然后才能访问类里的变量和方法。
若是静态类的话,就直接创建就行了,因为static类随着类的加载而加载。不用创建new Test6_extends()。
Inner1 inner1 = new Inner1();
作者: 马州州    时间: 2012-7-31 21:13
王志明 发表于 2012-7-31 20:59
将Inner1改成非静态也可以访问

?????改了就不能用了
你试试看撒
作者: 王志明    时间: 2012-7-31 21:20
马州州 发表于 2012-7-31 21:13
?????改了就不能用了
你试试看撒

我没说全,Inner2也改成非静态,呵呵
作者: 王志明    时间: 2012-7-31 21:58
问题已解决,谢谢同学们




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2