首页 > 代码库 > JAVASE复习

JAVASE复习

top

暑假每天中午更新

 

 

六花酱赛高

 

 

目录:

  内部类

  枚举类

  垃圾回收

  修饰符

  与运行环境交互

 

        

 

内部类:

 

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,局部内部类可能重名,所以N1开始递增

 

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 }

 

 

垃圾回收:

  1. 对象的三个状态:可达、可恢复、不可达
  2. System.gc() = Runtime.getRuntime().gc()

   System.runFinalization() = Runtime.getRuntime().runFinalization()

  1. System.gc()之后Thread.sleep(int time), 几秒之后效果更好
  2. 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 }

 

 

  1. Gc只是建议jvm收集垃圾! runFinalization只是建议jvm调用可恢复对象的finalize方法
  2. 要想让gc更有效率,就得深入学习java垃圾回收机制以及优化,别再想强行释放的问题了
  3. 程序结束时可能先关闭标准输出流,再调用垃圾对象的finalize方法,所以你不一定能在小程序中看到 finalize方法的输出。又或者调用finalize方法的途中关闭标准输出流,所以肯能只输出到一句,第 二句就不输出了

 

  4. 讲到gc,就得知道java1.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()方法或RuntimeloafLibrary()方法加载 第三部产生的动态链接库文件,

      就可以在Java中调用这个native()方法了。

transient: 没学

volatile: 跟线程原子性有关,忘了是啥,回头研究研究

 

 

与运行环境交互

  1. Scanner实例化时可指定输入流,也可以指定文件,不只有标准输入System.in~

Scanner一行一行地读取文件内容也是很方便的哦~

  2. System代表当前java程序的运行平台,不能实例化。提供标准输入、输出、错误,

可以得到环境变量等系统参数

  3. Runtime代表当前java的运行时环境,不能实例化,只能通过Runtime.getRuntime()

获取实例,可以得到处理器数量、空闲内存数等参数。可以另外启动一个进程来运行操作

系统的命令

  4. 工具类一般以s结尾,如ArraysCollectionsjava7新增的Objects

  5. BigDicemal实例化时要用字符串作为构造器参数,否则浮点数后面几位的随机数会导致精度

不好

 

  7/13  更新