this

用于方法跟构造器中, 在方法中returen this 返回当前对象 , 在构造器中this+对应的参数,可以指代指代的构造器,且只能调用一次构造器, 而且必须得在程序的一开始,java不允许构造器之外的方法来调用构造器

  1. public class Flower {
  2. int petalCount = 0;
  3. String s = "initial value";
  4. Flower(int petals) {
  5. petalCount = petals;
  6. System.out.println("Constructor w/ int arg only, petalCount = " + petalCount);
  7. }
  8. Flower(String ss) {
  9. System.out.println("Constructor w/ string arg only, s = " + ss);
  10. s = ss;
  11. }
  12. Flower(String s, int petals) {
  13. this(petals);
  14. //- this(s); // Can't call two!
  15. this.s = s; // Another use of "this"
  16. System.out.println("String & int args");
  17. }
  18. Flower() {
  19. this("hi", 47);
  20. System.out.println("no-arg constructor");
  21. }
  22. void printPetalCount() {
  23. //- this(11); // Not inside constructor!
  24. System.out.println("petalCount = " + petalCount + " s = " + s);
  25. }
  26. public static void main(String[] args) {
  27. Flower x = new Flower();
  28. x.printPetalCount();
  29. }
  30. }

static

static里面不能有this, 静态方法里不能调用非静态的方法, 但是反之可以

垃圾回收

请注意,垃圾回收只跟内存有关,垃圾回收的唯一目的就是回收程序不再使用的内存

finalize()

从上一条可知,java的垃圾回收只跟内存有关, 而finalize()方法适用的是非正常java模式下创建的对象, 在java的本地方法中, 可以运行c c++这两种语言,但是这两种语言又可以调用其他语言,所以实际上本地方法可以运行所有语言, 此时这些语言产生的垃圾, 你就需要在finalize()方法里来调用相应垃圾的清除方法(C,C++语言的清理垃圾方法)

用法就是重写finalize()方法

 @Override
    protected void finalize() throws Throwable {
        if (checkedOut) {
            System.out.println("Error: checked out");
        }
        // Normally, you'll also do this:
        // super.finalize(); // Call the base-class version
    }

当然 finalize还有一个比较有趣的用法 —- 对象终结条件验证
就是看某些不容易被清除的对象到底有没有被清除, 也就是垃圾回收的时候会触发finalize(), 你改写该方法, 来做状态判断, 这样 通过状态判断后的结果 就可以知道这个东西有没有被清除掉

java的垃圾回收机制会提高创建对象的效率

C跟C++ 的堆像一个院子, 有的对象负责凉亭,有的负责假山, 当对象被清除的时候,又会有新的对象来负责凉亭或者假山
而Jave不同,它更像是一个传送带,来一个对象,挪一格, 这样就意味着它为对象分配的速度会很快,而且java的”堆指针”只是简单的挪到空位子上,这使它的对象分配效率跟c ,c++在栈上分配对象的速度相当, 但是java却也不是完全类似一个传送带, 因为如果是像一个传送带的话, 那么对象一多,那么对象移进移出,就会产生很多页面调度,很多被移出的空间会空着, 但是有垃圾处理机制在,就会降低这种情况的发生, 因为垃圾处理机制会及时清除垃圾, 并且重新排列对象,使他们排列的更密集, 使堆指针更容易移动到传送带的开始处,这样就大大的提高了对象的创建效率

java的垃圾回收策略

计数清除

其他的系统有的是以计数的形式来回收垃圾的, 被调用就+1,离开作用域或者被设为null就减1,当计数为0时,清除 但这样如果一个对象被循环引用,那么它们的引用计数都不为0, 不为0就没法被清除,要清除循环引用,就需要耗费更待的工作量来处理

在更快的清除决策中, 不用计数方法,而是判断对象是不是活的,即一定能追溯到它在栈或者静态区的引用存在,在这种方式下java虚拟机采用一种自适应模式, 不同的虚拟机的自适应模式不同

停止-复制:停止运行的程序, 将一个对象从一个堆复制到另一个堆,复制的时候重新排列整理,更密集,但是缺点就是占有一倍的内存,而且来回倒腾也降低效率,而且当程序稳定以后,产生的垃圾其实很少的, 这样来回复制就得不偿失了

标记-清除:对活的对象进行标记, 之后清除未被标记的对象, 标记-清除后剩下的空间是不连续的, 如果让空间连续就得进行重新整理

如前文所述,这里讨论的 Java 虚拟机中,内存分配以较大的”块”为单位。如果对象较大,它会占用单独的块。严格来说,”停止-复制”要求在释放旧对象之前,必须先将所有存活对象从旧堆复制到新堆,这导致了大量的内存复制行为。有了块,垃圾回收器就可以把对象复制到废弃的块。每个块都有年代数来记录自己是否存活。通常,如果块在某处被引用,其年代数加 1,垃圾回收器会对上次回收动作之后新分配的块进行整理。这对处理大量短命的临时对象很有帮助。垃圾回收器会定期进行完整的清理动作——大型对象仍然不会复制(只是年代数会增加),含有小型对象的那些块则被复制并整理。Java 虚拟机会监视,如果所有对象都很稳定,垃圾回收的效率降低的话,就切换到”标记-清扫”方式。同样,Java 虚拟机会跟踪”标记-清扫”的效果,如果堆空间出现很多碎片,就会切换回”停止-复制”方式。这就是”自适应”的由来,你可以给它个啰嗦的称呼:”自适应的、分代的、停止-复制、标记-清扫”式的垃圾回收器。

java提速有很多方法

其中一种就是即时编译器技术,将全部或者部分程序翻译成本地机器码,这样的话就不需要用JVM来进行翻译了,当需要装载某个类(通常是创建该类的第一个对象)时,编译器会先找到其 .class 文件,然后将该类的字节码装入内存,这样就提高了速度, 但是它有两个缺点 1.是加载动作贯穿程序一生,累加起来的时间可能更多(用一次加载一次), 第二个就是增加代码长度(字节码比机器码短很多),后来出现了惰性评估-就是不盲目的全都用及时编译器, 只在有必要的时候进行编译, 而未执行的根本不用编译, 这就节省很多时间

初始化顺序

在类里变量定义的顺序觉得了它们初始化顺序, 及时变量定义分布在方法之间,它们仍会在任何方法(包括构造器)执行之前得到初始化,也就是有new 的 就先从上到下new, 之后再从上到下运行方法, 在方法里就是从上到下
静态对象初始化优先级高于非静态对象,但是静态对象只初始化一次,要是没被调用就不会初始化

引用的默认值为null

枚举

枚举是类, 创建一个枚举时,编译器会自动加上toString()方法 , 也会创建ordinal()方法,来标识枚举的声明顺序,枚举要大写