第三章 面对对象基本概念

堆与栈

1.面对对象编程的三大特性:封装性、继承性、多态性
2.属性+方法=成员+行为
3.在主类中定义并且由主方法调用的方法必须加上static,由对象调用的方法不需要加
4.在对象创建中还会涉及到栈内存和堆内存的问题
例:Book books = new Book();
在new一个对象的时候会使用栈内存和堆内存,栈内存中存放着对应对象的堆内存地址,堆内存中存放着对象的属性数据。
new的作用就是开辟一个堆内存。没有执行new的时候对象是不存在堆内存的,也就是说对象对应的栈内存没有指向任何一个堆内存。
5.关于GC的问题
GC最核心的功能就是对内存中的对象进行内存的分配和回收,当创建一个对象时,GC会对对象的地址、大小、状态进行监控。对象的引用会保存在栈(stack)中,对象的具体内容会保存在栈内存指向的堆内存中。当GC检测到某个堆内存不在被任何栈所引用时,就会不定期的对这个堆内存的对象进行回收。
java在针对垃圾收集也提供了多种不同的处理分类:
(1)引用计数
一个实例化的对象,程序使用了这个对象则引用计数加一,对象使用完毕则引用计数减一,当计数为零时则可以回收。
(2)跟踪收集:也就是说若A对象引用了B对象,则虚拟机会记住这个路径,而一个对象如果没有了路径,则会被回收。
(3)基于对象跟踪的分代收集器:根据堆内存的结构划分来进行收集
JVM将整个堆分成了以下三代:
A.YoungGen(新生代,使用Minor GC回收) 在这一空间中的对象生命周期比较短,GC对这些对象的回收采用复制拷贝法。
在这个堆又分为了eden、survivor1、survivor2。eden是在每个对象创建的时候会分配的空间,当eden无法分配时则会自动触发一次minor GC。每次GC执行时都会将eden和survivor1中的内容复制到survivor2中,然后清空eden和survivor1.GC执行下次回收时则会将eden和survivor2中的内容复制到survivor1中。经过数次的回收依然存活的对象则复制到老代区。
B.OldGen(年老代,使用major GC回收) 当新代的数据复制到了老代区以后会根据老代的剩余空间作出不同的处理。
若空间小于要保存的对象,则进行一次Full GC (对整个堆进行扫描和回收),这样就可以让OldGen腾出更多的空间,然后执行minor GC将对象复制到OldGen中。
若空间大于要保存的对象则会根据条件进行Minor GC和Full GC回收。
C.(持久区) 要存放加载进来的类信息,包括方法属性对象池等。
6.匿名对象 new Book()在堆内存中有数据,但在栈内存中没有对应的引用,使用一次后就成为了内存垃圾。

数组以及字符串STRING

7.数组的复制
System.arraycopy(源数组名称,源数组复制开始索引,目标数组名称,目标数组复制开始索引)
数组排序(能对基本数据类型数组进行从小到大自动排序)
java.util.Arrays.sort(数组名称)
8.对象数组的存放
在这里插入图片描述

9.String类型的实例化方式有两种
① String st = “caicaikan”
② String st = new String(“caiciakan”)
第一种方法实例化对象,会在堆内存中开辟出一个空间来存放"caicaikan",并且栈内存中的st会指向这个堆内存,经过这种方法实例化的对象会被加入对象池,在对象池中的对象可以被重用。(在JVM底层会存在一个对象池,对象池中不一定只保存String对象,当代码中采用直接赋值的方式定义了一个String对象时,会被加入对象池。)其他不采用直接赋值方式(用new的方式实例化的)创建的对象可以采用手动入池的方式加入对象池(intern())。
第二种方法实例化对象时,因为同时使用到了字符串和new关键字,所以会存在两个堆空间存放着相同的字符串(一个是字符串创建的匿名对象,另一个是new出来的),匿名对象之后会变成内存垃圾。

10.字符串的比较
在java中“==”比较可以用在基本数据类型和引用数据类型。在基本数据类型中是意味着比较变量或者常量值的大小,在引用类型中,尤其是在String中,双等号的比较比较的是地址的数值。在String中可以采用equals()方法进行比较 str.equals(str1)

11.字符串一旦定义了str1,其内容就不会改变,若是执行向这个字符串添加其他字符串str2的操作,则字符串str1+str2会放在其他的堆空间,不会是str1原来的空间。只是栈中str1指向的堆改变了。所以频繁的修改字符串会造成大量的垃圾空间。
12.String类的常用方法
在这里插入图片描述
在这里插入图片描述
13.String的长度运用st.length()调用,而数组中是a.length

关键字

14.this关键字:运用this关键字可以调用后本类的属性、本类的方法、通过this()调用构造方法以及代表当前的对象。
15.引用传递
基本数据类型传递的是数值,而String传递的是字符串的引用
static关键字
16.static关键字
java中主要存在4块内存空间:堆内存空间、栈内存空间、全局数据区(保存static类型的属性)、全局代码区(保存所有的方法定义)
static定义的属性和方法都不受实例化对象的控制,可以直接用类名进行调用。在类中带static和不带static的属性和方法之间的访问是有限制的:
①static方法是不能直接访问非static属性和方法,只能调用static属性和方法。
②非static方法可以访问static的属性和方法,不受任何的限制。
在不保存普通属性时可以把所有的方法定义成static属性,这样可以堆内存,因为对象属性是保存在堆内存中的。
由于主方法是由static定义的,所以若要在主方法中直接调用方法,则需要把方法定义成static属性。
在主方法中存在参数String arg[],这是指程序运行时传递的参数,格式为“java 类名 参数 参数 参数”,这是指向某个类传递参数,java为执行程序,参数最终会出现在arg数组中。

代码块

17.代码块
①普通代码块:在方法内由{}框起来的代码->在执行时正常执行,只是这些代码框在一起而已
②构造快:写在一个类里(不在方法里)的代码->无论构造快放在类中的顺序如何,它都先于构造函数执行。并且每次实例化一个对象都会执行一次。
③静态块:用static定义的构造快->先于构造快以及构造函数执行,在多次实例化中只执行一次。现在静态块应该已经不能用了。

内部类

18.内部类
内部类是一种类的结构扩充,一个类的内部除了属性和方法外还能存在其他的类结构,并且内部类也可以定义在方法或者代码块中。
内部类最大的好处就是能够轻松的访问外部类中的私有化属性。若是内部类和外部类都有相同的属性,则可以通过this来区分,访问内部类属性 this.属性,若访问外部类属性 外部类名.this.属性。
若要在外部直接创建内部类的对象,则 外部类.内部类 对象 = new 外部类().new 内部类();若内部类被定义为private则不能在外部创建对象,这个内部类只能够供外部类使用。
若是将内部类定义成static属性,则这内部类变成了“外部类”,在外部定义对象时可使用 外部类.内部类 对象 = new 外部类.内部类();进行创建。并且这个内部类只能操作外部类中的static属性。
19.在方法中也可以定义内部类(理论上可以在类的任何位置进行定义),定义在方法体内的内部类访问方法的参数或者变量,这些参数或者变量需要加上final属性(虽然JDK1.8以后不用加,但要有好的习惯)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值