黑马程序员技术交流社区

标题: 内部类的疑惑 [打印本页]

作者: 周志龙    时间: 2013-10-1 08:24
标题: 内部类的疑惑
本帖最后由 Nocturne 于 2013-10-2 23:12 编辑

现在学内部类,看着内部类和外部类调来调取的很头疼,谁能给我讲下它们的内存分布机制?还有对象
作者: 梦航    时间: 2013-10-1 08:43
明确如下几点:
非静态内部类:
    非静态内部类对象里一定是寄存了外部类的对象,但外部类对象不一定寄存了非静态内部类对象
静态内部类:
    静态内部类是类相关的,是与外部类的类相关,而不是与其对象相关,也就是说内部类对象寄存了外部类的类引用,如果此时采用内部类对象访问外部类对象时,将会引起错误

祝编程愉快!
作者: IT_JM    时间: 2013-10-1 16:42
内部类

使用情况:但描述事物时, 事物的内部还有事物,该事物用内部类来描述
                 因为内部事务在使用外部事务的内容

内部类的访问规则:
1,内部类可以直接访问外部类中的成员,包括私有。
        之所以可以直接访问外部类的成员,是因为内部类持有了一个外部类的引用,格式:外部类名.this
2, 外部类要访问内部类,必须先建立内部类对象。

访问格式:
1,当内部类定义在外部类的成员位置上,而且非私有,
   可以在外部其他类中访问,需要直接建立内部类对象。
   格式:
                外部类名.内部类名  变量名  =  外部类对象.内部类对象
                Outer.Inner in = new Outer().new Inner();
2,当内部类在成员位置上,就可以被成员修饰符所修饰。
        比如  private:将内部类在外部类中进行封装。
                  static:内部类就具备static的特性。
                  当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问局限。
               
                在外部其他类中,如何直接访问static内部类的非静态成员呢?
                new Outer.Inner().function();

                在外部其他类中,如何直接访问static内部类的静态成员呢?
                Outer.Inner.function();

注意:当内部类定义了static成员时,内部类必须声明为static的
          当外部类的静态方法访问内部类是,内部类也必须是static的

内部类定义在局部时:
1,不可以被成员修饰符修饰。
2,可以直接访问外部类成员, 因为还持有外部类中的引用。
  但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部变量。

匿名内部类:
1,匿名内部类其实就是内部类的简写格式。
2,定义匿名内部类的前提:
        内部类必须是继承一个类或实现接口。
3,匿名内部类的格式:new 父类或者接口(){定义子类的内容}
4,其实匿名内部类就是一个匿名子类对象,而且这个对象有也可以点胖。
        也可以理解为带内容的对象。
5,匿名内部类中定义的方法中最好不要超过3个

作者: 杨增坤    时间: 2013-10-1 21:22
你可以把内部类当成成员来理解,但是毕竟他是一个类,同时还要符合类的特征,

当成类的成员时候:根据权限不同,调用的方式也不一样,
假如内部类放在了方法中,那么就当作局部变量来考虑。

这样你更有利于你理解内部类!

希望对你有帮助!

作者: 凝聚    时间: 2013-10-1 22:01
Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管理与

内存泄露以及Java垃圾回收方面的知识,今天我们再次深入Java核心,详细介绍一下Java

在内存分配方面的知识。一般Java在内存分配时会涉及到以下区域:

◆寄存器:我们在程序中无法控制

◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中

◆堆:存放用new产生的数据

◆静态域:存放在对象中用static定义的静态成员

◆常量池:存放常量

◆非RAM存储:硬盘等永久存储空间

在函数中定义的一些基本类型的变量数据和对象的引用变量都在函数的栈内存中分配。当

在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当该变量退出

该作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作

他用。

堆内存用来存放由new创建的对象和数组。在堆中分配的内存,由Java虚拟机的自动

垃圾回收器来管理。

在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变

量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变

量。引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的

引用变量来访问堆中的数组或对象。引用变量就相当于是为数组或者对象起的一个名称。

引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被

释放。而数组和对象本身在堆中分配,即使程序运行到使用new产生数组或者对象的语句

所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指

向它的时候,才变为垃圾,不能在被使用,但仍然占据内存空间不放,在随后的一个不确

定的时间被垃圾回收器收走(释放掉)。这也是Java比较占内存的原因。实际上,栈中的变量指向堆内存中的变量,这就是Java中的指针!

常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。除了

包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的

常量值(final)还包含一些以文本形式出现的符号引用,比如:

◆类和接口的全限定名;

◆字段的名称和描述符;

◆方法和名称和描述符。

虚拟机必须为每个被装载的类型维护一个常量池。常量池就是该类型所用到常量的一个

有序集和,包括直接常量(string,integer和floatingpoint常量)和对其他类型,字段

和方法的符号引用。

对于String常量,它的值是在常量池中的。而JVM中的常量池在内存当中是以表的形

式存在的,对于String类型,有一张固定长度的CONSTANT_String_info表用来存储文字

字符串值,注意:该表只存储文字字符串值,不存储符号引用。说到这里,对常量池中的

字符串值的存储位置应该有一个比较明了的理解了。

在程序执行的时候,常量池会储存在MethodArea,而不是堆中。

Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、

anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃

圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,

因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。

但缺点是,由于要在运行时动态分配内存,存取速度较慢。

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈

中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量数

据(int,short,long,byte,float,double,boolean,char)和对象句柄(引用)。

栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:?

int

int

int

inta=3;

?int

int

int






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