当前位置:网站首页 > Java基础 > 正文

java零基础对象和类



小伙伴们,小编又来了,这篇文章承接上文,本节将详细讲解内部,学完本文章,面向对象编程也告一段落了,我们开始学习了。

第三节 内部类

https://www.bilibili.com/video/BV1L7411N77n/?p=110

内部类是一类特殊的类,指的是定义在一个类的内部的类。实际开发中,为了方便的使用外部类的相关属性和方法,这时候我们通常会定义一个内部类。

一般情况,我们把类定义成独立的单元。有些情况下,我们把一个类放在另一个类的内部定义,称为内部类(innerclasses)。

在Java中内部类主要分为成员非静态成员内部类、静态成员内部类、局部内部类、匿名内部类。

3.1 非静态成员内部类

https://www.bilibili.com/video/BV1L7411N77n/?p=111

作为类的成员存在,和成员变量、成员方法、构造方法、代码块并列。因为是类的成员,所以非静态成员内部类可以使用public、protected 、默认、private修饰,而外部类只能使用public、默认修饰。

【示例11】非静态成员内部类


总结1:基本特征

  •  内部类可以直接访问外部类的成员

  •  外部类不能直接访问内部类的成员,需要先创建对象再通过对象名访问

  •  内部类如何访问外部类的同名成员变量:OuterClass.this.num

  •  必须先创建外部类的对象,才能创建内部类的对象。非静态成员内部类是属于某个外部类对象的

总结2:更多特征

  •  非静态内部类不能有静态方法、静态属性和静态初始化块。

  •       外部类的静态方法、静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义变量、创建实例。

3.2 静态成员内部类

【示例12】静态成员内部类



总结:

  •  静态内部类只能够访问外部类的静态成员

  •  静态内部类如何访问外部类的同名的成员变量:OuterClass.num

  •  静态内部类属于整个外部类的。创建静态内部类的对象,不需先创建外部类的对象

  •  外部类可以通过类名直接访问内部类的静态成员,访问非静态成员依旧需要先创建内部类对象。

3.3 局部内部类

还有一种内部类,它是定义在方法内部的,作用域只限于本方法,称为局部内部类。

局部内部类的的使用主要是用来解决比较复杂的问题,想创建一个类来辅助我们的解决方案,到那时又不希望这个类是公共可用的,所以就产生了局部内部类。局部内部类和成员内部类一样被编译,只是它的作用域发生了改变,它只能在该方法中被使用,出了该方法就会失效。

局部内部类在实际开发中应用很少。

【示例13】局部内部类


注意:局部内部类访问所在方法的局部变量,要求局部变量必须使用final修饰。JDK1.8中final可以省略,但是编译后仍旧会加final。

第四节 虚拟机和垃圾回收

https://www.bilibili.com/video/BV1L7411N77n/?p=79

4.1 匿名内部类

匿名内部类就是内部类的简化写法,是一种特殊的局部内部类。

前提:存在一个类或者接口,这里的类可以是具体类也可以是抽象类。

本质是什么呢?是一个继承了该类或者实现了该接口的子类匿名对象。

适合那种只需要创建一次对象的类。比如:Java GUI编程、Android编程键盘监听操作等等。比如Java开发中的线程任务Runnble、外部比较器Comparator等。

语法:



问题:一个类实现Comparable接口,只能指定一种比较大小的规则,如果需要有更多的比较规则,怎么办?


/p>

p class="MsoNormal">Comparable:内部比较器   public class Student implements Comparable{} 内部比较器只能有一个,一般采用最经常使用的比较规则

/p>

p class="MsoNormal">Comparator 外部比较器  可指定多个 不需要Student实现该接口,而是定义专门的类。

/p>

p class="MsoNormalIndent" style="margin-left:0.0000pt;mso-para-margin-left:0.0000gd;text-indent:0.0000pt;

mso-char-indent-count:0.0000;">

br/>

br/>

span class="font-size-16">【示例14】定义Comparator接口

/span>

img src="https://i0.hdslb.com/bfs/article/a0814d3d0ebfbb8e8e4d73692747b52d51868588.png" data-src="https://i0.hdslb.com/bfs/article/a0814d3d0ebfbb8e8e4d73692747b52d51868588.png" width="610" height="381" data-size="27758"/>

figcaption class="caption" contenteditable="">

/figcaption>

strong>

/strong>

br/>

strong>

/strong>

span class="font-size-16">【示例15】实现Comparator接口的类

/span>

img src="https://i0.hdslb.com/bfs/article/064c538d6caee1964d2e1dc5726b6bd53766799c.png" data-src="https://i0.hdslb.com/bfs/article/064c538d6caee1964d2e1dc5726b6bd53766799c.png" width="610" height="759" data-size="70389"/>

figcaption class="caption" contenteditable="">

/figcaption>

p>


/p>

strong>


/strong>

br/>

span class="font-size-16">【示例16】使用匿名内部类实现外部比较器

/span>

img src="https://i0.hdslb.com/bfs/article/8659b6229dce0896e7d09cedffcafcc30eeddb78.png" data-src="https://i0.hdslb.com/bfs/article/8659b6229dce0896e7d09cedffcafcc30eeddb78.png" width="610" height="1011" data-size="99401"/>

figcaption class="caption" contenteditable="">

/figcaption>

strong>

/strong>

br/>

strong>

/strong>

span class="color-pink-03">结论:

/span>

li>

匿名内部类可以实现一个接口,也可以继承一个类(可以是抽象类)。

/li>

li>

 匿名内部类只能实现一个接口,而不是多个

/li>

li>

 必须实现所有的方法,匿名内部类不能是抽象类

/li>

li>

 匿名内部类不可能有构造方法,因为类是匿名的

/li>

li>

 匿名内部类没有访问修饰符

/li>

li>

 如果想实现构造方法的一些初始化功能,可以通过代码块实现

/li>

li>

 如果要访问所在方法的局部变量,该变量需要使用final修饰。(JDK1.8可省略final)

/li>

span class="font-size-16">

4.2 内部类的作用和使用场合

/span>

strong>

/strong>

span class="color-pink-03">

内部类的作用

/span>

li>

 内部类提供了更小的封装。只能让外部类直接访问,不允许同一个包中的其他类直接访问。

/li>

li>

内部类可以直接访问外部类的私有属性,内部类被当成其外部类的成员。 但外部类不能访问内部类的内部属性。

/li>

li>

 接口只是解决了多重继承的部分问题,而内部类使得多重继承的解决方案变得更加完整。

/li>

li>

 用匿名内部类实现回调功能。我们用通俗讲解就是说在Java中,通常就是编写一个接口,然后你来实现这个接口,然后把这个接口的一个对象作以参数的形式传到另一个程序方法中, 然后通过接口调用你的方法,匿名内部类就可以很好的展现了这一种回调功能

/li>

strong>内部类的使用场合:

/strong>

li>

 由于内部类提供了更好的封装特性,并且可以很方便的访问外部类的属性。所以,在只为外部类提供服务的情况下可以优先考虑使用内部类。

/li>

li>

 使用内部类间接实现多继承:每个内部类都能独立地继承一个类或者实现某些接口,所以无论外部类是否已经继承了某个类或者实现了某些接口,对于内部类没有任何影响。

/li>

strong>

4.3

/strong>

strong>

 

/strong>

strong>

虚拟机及其构成

/strong>

strong>

/strong>

img src="https://i0.hdslb.com/bfs/article/83f6b07a3ae6c798ac03362bf19d38395e9e14c0.png" data-src="https://i0.hdslb.com/bfs/article/83f6b07a3ae6c798ac03362bf19d38395e9e14c0.png" width="314" height="225" data-size="66543"/>

figcaption class="caption" contenteditable="">

/figcaption>

strong>

程序计数器

/strong>

strong>

Java虚拟机栈和本地方法栈

/strong>

strong>

Java堆

/strong>

strong>

方法区

/strong>

br/>

br/>

img src="https://i0.hdslb.com/bfs/article/7b5579ccf576d3e98c875c8eeceb2face1557ddb.png" data-src="https://i0.hdslb.com/bfs/article/7b5579ccf576d3e98c875c8eeceb2face1557ddb.png" width="516" height="449" data-size="142493"/>

figcaption class="caption" contenteditable="">

/figcaption>

strong>

/strong>

strong>堆内存分为三部分

/strong>

br/>

strong>年轻代:分为eden区+两个大小相同的存活期s0、s1;

/strong>

strong>老年代

/strong>

strong>永久代

/strong>

strong>注意:

/strong>JDK6 及以前版本,字符串常量池是放在堆的Perm区的,Perm区是一个类静态的区域,主要存储一些加载类的信息,常量池,方法片段等,默认大小只有4m,一旦常量池中大量使用 intern 是会直接产生java.lang.OutOfMemoryError:PermGen space错误。

strong>

4.4

/strong>

strong>

 

/strong>

strong>

垃圾回收

/strong>

strong>

/strong>

strong>分代垃圾回收机制

/strong>,是基于这样一个事实:不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的回收算法,以便提高回收效率。我们将对象分为三种状态:年轻代、年老代、持久代。同时,将处于不同状态的对象放到堆中不同的区域。 JVM将堆内存划分为 Eden、Survivor 和 Tenured/Old 空间。

span class="font-size-12">

/span>

strong>

 垃圾回收的相关技能点

/strong>

p class="16" style="margin-left:36.7500pt;text-indent:-21.0000pt;mso-char-indent-count:0.0000;

mso-layout-grid-align:none;layout-grid-mode:char;mso-list:l0 level1 lfo1;">垃圾回收机制主要是回收JVM堆内存里的对象空间。

/p>

p class="16" style="margin-left:36.7500pt;text-indent:-21.0000pt;mso-char-indent-count:0.0000;

mso-layout-grid-align:none;layout-grid-mode:char;mso-list:l0 level1 lfo1;">现在的JVM有多种垃圾回收实现算法,表现各异。

/p>

p class="16" style="margin-left:36.7500pt;text-indent:-21.0000pt;mso-char-indent-count:0.0000;

mso-layout-grid-align:none;layout-grid-mode:char;mso-list:l0 level1 lfo1;">垃圾回收发生具有不可预知性,程序无法精确控制垃圾回收机制执行。

/p>

p class="16" style="margin-left:36.7500pt;text-indent:-21.0000pt;mso-char-indent-count:0.0000;

mso-layout-grid-align:none;layout-grid-mode:char;mso-list:l0 level1 lfo1;">可以将对象的引用变量设置为null,暗示垃圾回收机制可以回收该对象。

/p>

p class="16" style="margin-left:36.7500pt;text-indent:-21.0000pt;mso-char-indent-count:0.0000;

mso-layout-grid-align:none;layout-grid-mode:char;mso-list:l0 level1 lfo1;">程序员可以通过System.gc()或者Runtime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行垃圾回收依然不确定。

/p>

p class="16" style="margin-left:36.7500pt;text-indent:-21.0000pt;mso-char-indent-count:0.0000;

mso-layout-grid-align:none;layout-grid-mode:char;mso-list:l0 level1 lfo1;">垃圾回收机制回收任何对象之前,总会先调用它的finalize方法(如果覆盖该方法,让一个新的引用变量重新引用该对象,则会重新激活对象)。

/p>

p class="16" style="margin-left:36.7500pt;text-indent:-21.0000pt;mso-char-indent-count:0.0000;

mso-layout-grid-align:none;layout-grid-mode:char;mso-list:l0 level1 lfo1;">永远不要主动调用某个对象的finalize方法,应该交给垃圾回收机制调用。

/p>


【示例17】finalize()和gc()

版权声明


相关文章:

  • java零基础入门教程272024-10-19 16:02:02
  • java基础语法口诀2024-10-19 16:02:02
  • java 算法基础之十大算法2024-10-19 16:02:02
  • JAVA基础教程PPT模板2024-10-19 16:02:02
  • 有java基础学测试2024-10-19 16:02:02
  • java大数据入门基础教程2024-10-19 16:02:02
  • java语言基础整数2024-10-19 16:02:02
  • java回文数基础代码2024-10-19 16:02:02
  • java基础能应聘什么岗位2024-10-19 16:02:02
  • 用java基础编程游戏2024-10-19 16:02:02