首页 > 代码库 > JAVASE复习
JAVASE复习
暑假每天中午更新
六花酱赛高
目录:
内部类
枚举类
垃圾回收
修饰符
与运行环境交互
内部类:
1. 外部类可以通过非静态内部类对象访问内部类的private属性,内部类可以直接访问外部类的private属性,说明外部类和内部类都是在“一个类中”,这样才能相互访问到对方的private属性
2. 非静态内部类的实例化:new Outer().new Inner();//这个很好理解,Inner需要用outer对象来实例化,Inner的命名空间是Outer
3. 静态内部类的实例化: new Outer.Inner();
4. 内部类的子类的构造器调用父类构造器,要加上外部类做为命名空间:
SubInner.java code:
1 class Outer1 { 2 class Inner {//注意权限限定,别private了,不然没法继承。如果是protected和默认权限,也要注意SubInner放在哪 3 private String name; 4 public Inner(String name) { 5 this.name = name; 6 } 7 } 8 } 9 10 public class SubInner extends Outer1.Inner {11 public SubInner(Outer1 out, String name) {12 out.super(name);13 //super(name);//是错的,说明内部类是有命名空间的14 //Outer1.super(name);//是错的,说明非静态内部类必须要存在于一个父类的实例中15 }16 }
5. 内部类生成的class文件:Outer$Inner.class
6. 局部内部类(在方法中定义的内部类)生成的class文件:OuterClass$NInner.class,局部内部类可能重名,所以N从1开始递增
7. 个人觉得java使用内部类实现闭包和回调华而不实
枚举类:
1. switch语句可以用枚举类来做判断
2. Enum可以implements interface但是不能 extends class。原因是enum自动继承java.lang.Enum,不能再继承其他的类了!
3. 枚举类的对象在定义时可用类似与匿名内部类的方式来重写方法、添加方法、添加属性等
4. 枚举类默认是public final的。但可以使用匿名内部类的方式来给枚举类对象初始化,是因为写匿名内部类的时候jvm自动把枚举类弄成abstract而不使用final,但这个abstract不能让你显式的写上去,而且在其他地方不能让你继承枚举类,就算是匿名内部类也不行,如:
Season.java code:
1 //class A extends Season {//错的,除了给枚举对象初始化时可以继承,其他地方都不能继承 2 // 3 //} 4 public enum Season {//extends 是被不允许的,因为java没有多继承 5 SPRING() {//使用匿名内部类给枚举对象初始化 6 int a; 7 8 @Override 9 void func() {10 11 }12 };13 abstract void func();//在enum中可以写抽象方法14 public static void main(String[] args) {15 //Season s = new Season() {};错,即使是匿名内部类继承,也不能使用16 }17 }
垃圾回收:
- 对象的三个状态:可达、可恢复、不可达
- System.gc() = Runtime.getRuntime().gc()
System.runFinalization() = Runtime.getRuntime().runFinalization()
- System.gc()之后Thread.sleep(int time), 几秒之后效果更好
- System.gc()之后System.runFinalization()类似于第三点,如:
Main.java code:
1 public class Main { 2 public static void main(String[] args) throws Exception { 3 for (int i = 0; i < 1000; ++i) { 4 new Main(); 5 } 6 System.gc(); 7 //Thread.sleep(10); 8 System.runFinalization(); 9 System.out.println("如果\"清理\"出现在下面,说明没有及时清理");10 // System.out.println(Runtime.getRuntime().freeMemory());11 }12 13 @Override14 public void finalize() {15 System.out.println("清理");16 }17 }
- Gc只是建议jvm收集垃圾! runFinalization只是建议jvm调用可恢复对象的finalize方法
- 要想让gc更有效率,就得深入学习java垃圾回收机制以及优化,别再想强行释放的问题了
- 程序结束时可能先关闭标准输出流,再调用垃圾对象的finalize方法,所以你不一定能在小程序中看到 finalize方法的输出。又或者调用finalize方法的途中关闭标准输出流,所以肯能只输出到一句,第 二句就不输出了
4. 讲到gc,就得知道java从1.2开始的4中引用:强引用、软引用、弱引用、虚引用
a) 平常用的就是强引用,强引用全部赋值为null时会回收,不一定会马上回收
b) 软引用SoftReference,在虚拟机内存不足的时候会释放,使用前先把强引用关
联软引用,然后把强引用赋值为null
c) 弱引用WeakReference,不管怎样,都回收,不一定立即回收。使用方法同上
d) 虚引用PhantomReference,无法从虚引用获得对象,与引用队列ReferenceQueue
联用,用来查看对象是否以被回收,如果被回收,那么引用队列中存在那个虚引用
修饰符:
strictfp: 用来修饰浮点数,将严格按照IEEE-754来计算,使得计算更精确
native: 本地方法,一般用C语言来写,用来调用一些跟平台有关的函数或链接库,定义之后
说明你的程序不再具有平台无关性。
使用方法:
1. 写native的方法声明,别写方法体
2. 用javah编译第一部生成的class文件,将产生一个.h文件(C语言中叫头文 件)。
3. 写一个.cpp文件实现native方法,其中需要包含第一部产生的.h头文件(.h 文件中又包含了JDK自带的jni.h文件).
4. 将第二部中的.cpp文件变异成动态链接库文件。
5. 在Java中调用System.loadLibrary()方法或Runtime的loafLibrary()方法加载 第三部产生的动态链接库文件,
就可以在Java中调用这个native()方法了。
transient: 没学
volatile: 跟线程原子性有关,忘了是啥,回头研究研究
与运行环境交互:
- Scanner实例化时可指定输入流,也可以指定文件,不只有标准输入System.in哦~
用Scanner一行一行地读取文件内容也是很方便的哦~
2. System代表当前java程序的运行平台,不能实例化。提供标准输入、输出、错误,
可以得到环境变量等系统参数
3. Runtime代表当前java的运行时环境,不能实例化,只能通过Runtime.getRuntime()
获取实例,可以得到处理器数量、空闲内存数等参数。可以另外启动一个进程来运行操作
系统的命令
4. 工具类一般以s结尾,如Arrays,Collections,java7新增的Objects
5. BigDicemal实例化时要用字符串作为构造器参数,否则浮点数后面几位的随机数会导致精度
不好
7/13 更新