Java(OOP)其他知识
1、static(静态)
被static修饰的成员(属性,方法),称为静态成员也叫类成员。他们是在类加载时完成
初始化。而且静态成员可以在没有创建对象时直接通过类就可以访问。
类成员也属于所有对象共享的成员。
静态变量:
在普通成员方法中可以定义静态变量吗? 不行
在构造方法中可以定义吗? 不行
静态方法:
直接通过类名就可以调用: 类.静态方法()
静态方法中也不能定义静态变量。
静态方法中不能使用非静态成员。
静态方法可以重载吗?---可以重载 --- 重载与方法签名相关
静态方法可以被继承吗?---可以
静态方法可以被重写吗?---不可以
如果子类中要定义与父类静态方法相同的方法,要么都为静态,要么都为非静态。
加载顺序: 父类静态-》子类静态-》父类非静态-》子类非静态
应用场景:
1-static只能用于修饰成员
2-static一般还用于设置常量
3-工具类中方法通常都是静态方法
2、final
final一般表示最终的,一旦被定义就不能修改。
1-在方法中使用final
变量前使用final修饰,如果变量是基础类型,则值不能修改;如果是引用类型,则引用地址
不能被修改。
2-用于修饰类
表示类不能被继承,该类也称为最终类。
3-设置常量
static final 使用在成员属性上,也表示常量。与上面的用发相同但是命名使用大写字母加
下划线。
例如: 图形类案例中圆周率是固定不变
private static final double PI = 3.14;
4-设置方法(最终方法)
方法被final修饰后,该方法不能被重写。
3、抽象(abstract)
被abstract修饰的类称为抽象类,被abstract修饰的方法称为抽象方法。
如果在类中只要有一个方法是抽象方法,这个类一定是个抽象类。
抽象类中不一定会存在抽象方法。
抽象类是不能直接实例化的,必须把抽象类中的所有方法全部实现(重写),继承是前提。
抽象类中可以定义构造方法吗? -- 可以
抽象方法可以用static/final来修饰吗?--不能
可以用private来修饰抽象方法吗? --不可以
如果抽象方法是用的默认权限修饰符,对子类有没什么要求?
子类和抽象类必须同包
使用场景:
如果一个类中一部分,暂时不能确定功能,需要后期在实现
这种方法就可以定义抽象发法并且把类也定义为抽象类
4、接口(interface)
如果一个抽象类中,所有方法都是抽象方法时,应该将该类定义为接口。
如果要使用接口,就需要用一个类实现(implements)接口,并实现里面所有抽象方法。
java类中对于接口是支持多实现;
在接口中允许定义常量。
在接口中只能有抽象方法吗? -- 不是,从jdk1.8开始支持如下的两种方法
静态方法
默认方法(被default修饰的方法)
5、内部类
在类/接口/方法中定义的类就是内部类
5、1 方法内部类(局部内部类)
在方法中定义的类。
方法内部类中可以访问外部类的所有成员,所在方法中的局部变量也可以访问,但是在方
法内部类中不能定义静态成员。
5、2 成员内部类
定义在类中,方法外。
除了定义的位置与方法内部类不同而外,其他都一样。
//访问成员内部类的方法
new 外部类().new 内部类().方法名();
5、3 静态内部类
成员内部类被static修饰。静态内部类中可以定义任意的成员。但是外部的非静态成员不能访问。
//访问静态内部类的方法
new 外部类().内部类().方法名();
5、4 匿名内部类
没有名字的内部类。通常伴随接口或抽象类出现。
new 接口/抽象类(){
//抽象方法的具体实现
}
匿名内部类中不能定义静态成员,能访问所在方法中的变量,但是不能访问外层类的非静态成员。
案例:
interface Day7Inter{
void prints();
void getInfo();
}
//使用匿名内部类实现接口中的抽象方法。
Day7Inter day7Inter = new Day7Inter() {
public void prints(){
}
public void getInfo(){
}
};
5、5 接口内部类
在接口中定义的类,默认就是public static。
5、6 内部接口
类/接口中定义接口--内部接口---默认是静态的
在java中,类的内部可以定义类也可以定义接口;接口中也能定义接口和类。
package包
1、package在其他语言中也叫命名空间(namespace),目的为了解决命名冲突。
2、package命名规范要求,多个层级的包中间使用.分隔,并且使用小写字母。
3、通常包的定义顺序是按照当前公司注册的域名倒写形式。 package cn.huaxin.projectname
4、如果在java文件中需要引入第三方的类完成操作,则需要通过import关键字导包。
但java中有个特殊的包 java.lang无需导入。
5、导包形式:
a、导入具体包,只需安装包的路径导入
b、如果需要对当前包下的直接类导入,则可以使用*代表通配符. import cn.huaxin.utils.*
c、如果一个类中所有的方法为静态方法,则可以使用静态导包,省略类名。
import static 工具类路径
6、java中常见包说明:
java.util---工具包---提供了一系列操作对象的类和方法,作为工具来使用
java.applet---小应用程序包---内嵌到浏览器
java.awt---图形界面+swing
java.io---数据传输
java.math---和数字以及数学运算有关的包
java.net---网络通信
java.nio---高并发(非阻塞式io)
java.security---数据安全
java.sql---和数据库进行交互
java.text---格式化
javax---是Java包的扩展包
org---第三方厂商提供的一些常用包
垃圾分代回收机制
1、定义
垃圾分代回收机制是整合了多种垃圾回收算法共同实现的。垃圾回收是针对jvm运行时内存中
堆内存。
2、如何判定垃圾对象
如果一个对象在程序中不再被引用,则该对象就是等待回收的垃圾对象。对象的引用都是通过
引用计数器完成的,引用计数为0表示没有引用。
以及通过GC Roots判定对象是否可达。
3、如何启动垃圾回收器清理垃圾?
java中的垃圾回收,是由独立的一个垃圾回收线程进行监控,和清理。程序员不需要管理。
不过在java的System类中提供了一个gc()方法,可以通知垃圾回收器进行清理,但不一定有用。
4、jvm运行时内存区域
栈内存:方法调用开辟栈空间。
堆内存:对象都被保存在堆内存中,所以也是垃圾回收关注的内存区,是所有内存中最大的区域。
方法区:保存类的接口信息,静态常量池。
本地方法栈: 主要用于处理java中的本地方法 native,本地方法是其他语言实现的。
寄存器:用于记录每个线程执行到的指令位置,是所有内存区中永远不会出现内存溢出的区域。
从jdk1.7开始,已经慢慢引入元空间的概念,主要是将原来的方法区中的一部分放到堆,另
一部分放到本地内存。
5、堆内存区域(垃圾回收区域)
堆区:
新生代:
伊甸园区
幸存区:
幸存区0
幸存区1
伊甸园区与幸存区的内存比例: 8:1:1
特点:内存大,对象存活率比较低。
适用于 复制算法,算法回收效率高。
复制算法必须要多余的空进行交换,所以内存使用率会下降。(空间换时间)
老年代:
垃圾回收频率比新生代更低,原因是里面存放的对象都是比较稳定的,如果不小心
把老年代中的对象全部清理,可能会导致jvm运行出错。
在老年代中可以使用如下的算法:
标记清除:
会产生大量的内存碎片。
内存分配效率低。
标记整理:
不会产生内存碎片。
在内存空间整理会消耗一定的效率。
注意:如果一个对象比较大,在新生代中无法存储,则该对象会直接保存到老年代,如果
老年代也无法保存,则抛出内存溢出错误。