zoukankan      html  css  js  c++  java
  • 关于初始化和清理

    1. this者谁?

    // housekeeping/PassingThis.java
    
    class Person {
        public void eat(Apple apple) {
            Apple peeled = apple.getPeeled();
            System.out.println("Yummy");
        }
    }
    
    public class Peeler {
        static Apple peel(Apple apple) {
            // ... remove peel
            return apple; // Peeled
        }
    }
    
    public class Apple {
        Apple getPeeled() {
            return Peeler.peel(this);
        }
    }
    
    public class PassingThis {
        public static void main(String[] args) {
            new Person().eat(new Apple());
        }
    }

    this简单来讲即使谁调代表谁,上面的代码就是this的一种用法,将自身引用传递出去。

    this的另一个常用地方就是this.super()等这种构造器中调用构造器,可以大量减少重复代码。

    // housekeeping/Flower.java
    // Calling constructors with "this"
    
    public class Flower {
        int petalCount = 0;
        String s = "initial value";
    
        Flower(int petals) {
            petalCount = petals;
            System.out.println("Constructor w/ int arg only, petalCount = " + petalCount);
        }
    
        Flower(String ss) {
            System.out.println("Constructor w/ string arg only, s = " + ss);
            s = ss;
        }
    
        Flower(String s, int petals) {
            this(petals);
            //- this(s); // Can't call two!
            this.s = s; // Another use of "this"
            System.out.println("String & int args");
        }
    
        Flower() {
            this("hi", 47);
            System.out.println("no-arg constructor");
        }
    
        void printPetalCount() {
            //- this(11); // Not inside constructor!
            System.out.println("petalCount = " + petalCount + " s = " + s);
        }
    
        public static void main(String[] args) {
            Flower x = new Flower();
            x.printPetalCount();
        }
    }

    这里的构造调用构造有两点要求,1是必须在开头调用,2是只能调用一个构造器(否则它就违背了第一点)。

    2. static者谁?

    它是为类创建的不是为对象创建的,听起来很别扭,但事实如此,因为它是不需要对象的支撑来调用的,这点和必须要有对象支撑的this截然相反,所以static中不能有this。它有点全局的语义,但是java并没有全局,所以它也是饱受人质疑的一点,它是否破坏了面向对象这个概念,我个人觉着是有一些的。

    3. 垃圾回收

    Java是有自己GC的,finalize()方法一般是不建议主动用的,我们需要关注的点应该是对象的引用上,比如链表,我们用数组实现的话,remove掉一个node,我们需要将该node的指针置为null。下面有一个手动gc的例子。

    // housekeeping/TerminationCondition.java
    // Using finalize() to detect a object that
    // hasn't been properly cleaned up
    
    import onjava.*;
    
    class Book {
        boolean checkedOut = false;
    
        Book(boolean checkOut) {
            checkedOut = checkOut;
        }
    
        void checkIn() {
            checkedOut = false;
        }
    
        @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
        }
    }
    
    public class TerminationCondition {
    
        public static void main(String[] args) {
            Book novel = new Book(true);
            // Proper cleanup:
            novel.checkIn();
            // Drop the reference, forget to clean up:
            new Book(true);
            // Force garbage collection & finalization:
            System.gc();
            new Nap(1); // One second delay
        }
    
    }

    4. 初始化,这块很基础了,就直接post代码了

    // housekeeping/OrderOfInitialization.java
    // Demonstrates initialization order
    // When the constructor is called to create a
    // Window object, you'll see a message:
    
    class Window {
        Window(int marker) {
            System.out.println("Window(" + marker + ")");
        }
    }
    
    class House {
        Window w1 = new Window(1); // Before constructor
    
        House() {
            // Show that we're in the constructor:
            System.out.println("House()");
            w3 = new Window(33); // Reinitialize w3
        }
    
        Window w2 = new Window(2); // After constructor
    
        void f() {
            System.out.println("f()");
        }
    
        Window w3 = new Window(3); // At end
    }
    
    public class OrderOfInitialization {
        public static void main(String[] args) {
            House h = new House();
            h.f(); // Shows that construction is done
        }
    }

    输出

    Window(1)
    Window(2)
    Window(3)
    House()
    Window(33)
    f()

    静态数据初始化

    // housekeeping/StaticInitialization.java
    // Specifying initial values in a class definition
    
    class Bowl {
        Bowl(int marker) {
            System.out.println("Bowl(" + marker + ")");
        }
    
        void f1(int marker) {
            System.out.println("f1(" + marker + ")");
        }
    }
    
    class Table {
        static Bowl bowl1 = new Bowl(1);
    
        Table() {
            System.out.println("Table()");
            bowl2.f1(1);
        }
    
        void f2(int marker) {
            System.out.println("f2(" + marker + ")");
        }
    
        static Bowl bowl2 = new Bowl(2);
    }
    
    class Cupboard {
        Bowl bowl3 = new Bowl(3);
        static Bowl bowl4 = new Bowl(4);
    
        Cupboard() {
            System.out.println("Cupboard()");
            bowl4.f1(2);
        }
    
        void f3(int marker) {
            System.out.println("f3(" + marker + ")");
        }
    
        static Bowl bowl5 = new Bowl(5);
    }
    
    public class StaticInitialization {
        public static void main(String[] args) {
            System.out.println("main creating new Cupboard()");
            new Cupboard();
            System.out.println("main creating new Cupboard()");
            new Cupboard();
            table.f2(1);
            cupboard.f3(1);
        }
    
        static Table table = new Table();
        static Cupboard cupboard = new Cupboard();
    }

    输出

    Bowl(1)
    Bowl(2)
    Table()
    f1(1)
    Bowl(4)
    Bowl(5)
    Bowl(3)
    Cupboard()
    f1(2)
    main creating new Cupboard()
    Bowl(3)
    Cupboard()
    f1(2)
    main creating new Cupboard()
    Bowl(3)
    Cupboard()
    f1(2)
    f2(1)
    f3(1)

    显示的静态初始化

    // housekeeping/ExplicitStatic.java
    // Explicit static initialization with "static" clause
    
    class Cup {
        Cup(int marker) {
            System.out.println("Cup(" + marker + ")");
        }
    
        void f(int marker) {
            System.out.println("f(" + marker + ")");
        }
    }
    
    class Cups {
        static Cup cup1;
        static Cup cup2;
    
        static {
            cup1 = new Cup(1);
            cup2 = new Cup(2);
        }
    
        Cups() {
            System.out.println("Cups()");
        }
    }
    
    public class ExplicitStatic {
        public static void main(String[] args) {
            System.out.println("Inside main()");
            Cups.cup1.f(99); // [1]
            Cups.cup1.f(99); // [1]
        }
    
        // static Cups cups1 = new Cups(); // [2]
        // static Cups cups2 = new Cups(); // [2]
    }

    输出

    Inside main()
    Cup(1)
    Cup(2)
    f(99)
    f(80)

    非静态的初始化

    // housekeeping/Mugs.java
    // Instance initialization
    
    class Mug {
        Mug(int marker) {
            System.out.println("Mug(" + marker + ")");
        }
    }
    
    public class Mugs {
        Mug mug1;
        Mug mug2;
        { // [1]
            mug1 = new Mug(1);
            mug2 = new Mug(2);
            System.out.println("mug1 & mug2 initialized");
        }
    
        Mugs() {
            System.out.println("Mugs()");
        }
    
        Mugs(int i) {
            System.out.println("Mugs(int)");
        }
    
        public static void main(String[] args) {
            System.out.println("Inside main()");
            new Mugs();
            System.out.println("new Mugs() completed");
            new Mugs(1);
            System.out.println("new Mugs(1) completed");
        }
    }

    输出,这里因为不是静态,所以基本每次都要重新把类的初始化流程走一遍

    Inside main
    Mug(1)
    Mug(2)
    mug1 & mug2 initialized
    Mugs()
    new Mugs() completed
    Mug(1)
    Mug(2)
    mug1 & mug2 initialized
    Mugs(int)
    new Mugs(1) completed

    5. 对于可变参数的重载

    // housekeeping/OverloadingVarargs2.java
    // {WillNotCompile}
    
    public class OverloadingVarargs2 {
        static void f(float i, Character... args) {
            System.out.println("first");
        }
    
        static void f(Character... args) {
            System.out.println("second");
        }
    
        public static void main(String[] args) {
            f(1, 'a');
            f('a', 'b');
        }
    }

    这段代码是编译不过的,因为不知道该调用哪个,这也是重载的一个常犯的错误,不过好处是编译就会发现这个错误不会产生事故。

    // housekeeping/OverloadingVarargs3
    
    public class OverloadingVarargs3 {
        static void f(float i, Character... args) {
            System.out.println("first");
        }
    
        static void f(char c, Character... args) {
            System.out.println("second");
        }
    
        public static void main(String[] args) {
            f(1, 'a');
            f('a', 'b');
        }
    }

    这样处理就可以了。

    6. 枚举类型,其实枚举的用处和性能很强,应该多用,比如替代掉比较传统的常量接口,后者对代码太具有污染性了

    // housekeeping/Spiciness.java
    
    public enum Spiciness {
        NOT, MILD, MEDIUM, HOT, FLAMING
    }
    // housekeeping/SimpleEnumUse.java
    
    public class SimpleEnumUse {
        public static void main(String[] args) {
            Spiciness howHot = Spiciness.MEDIUM;
            System.out.println(howHot);
        }
    }

    MEDIUM
    // housekeeping/EnumOrder.java
    
    public class EnumOrder {
        public static void main(String[] args) {
            for (Spiciness s: Spiciness.values()) {
                System.out.println(s + ", ordinal " + s.ordinal());
            }
        }
    }
    
    
    NOT, ordinal 0
    MILD, ordinal 1
    MEDIUM, ordinal 2
    HOT, ordinal 3
    FLAMING, ordinal 4

    enum还与switch绝配

    // housekeeping/Burrito.java
    
    public class Burrito {
        Spiciness degree;
    
        public Burrito(Spiciness degree) {
            this.degree = degree;
        }
    
        public void describe() {
            System.out.print("This burrito is ");
            switch(degree) {
                case NOT:
                    System.out.println("not spicy at all.");
                    break;
                case MILD:
                case MEDIUM:
                    System.out.println("a little hot.");
                    break;
                case HOT:
                case FLAMING:
                default:
                    System.out.println("maybe too hot");
            }
        }
    
        public static void main(String[] args) {
            Burrito plain = new Burrito(Spiciness.NOT),
            greenChile = new Burrito(Spiciness.MEDIUM),
            jalapeno = new Burrito(Spiciness.HOT);
            plain.describe();
            greenChile.describe();
            jalapeno.describe();
        }
    }
    一个没有高级趣味的人。 email:hushui502@gmail.com
  • 相关阅读:
    Codeforces 877 C. Slava and tanks
    Codeforces 877 D. Olya and Energy Drinks
    2017 10.25 NOIP模拟赛
    2017 国庆湖南 Day1
    UVA 12113 Overlapping Squares
    学大伟业 国庆Day2
    51nod 1629 B君的圆锥
    51nod 1381 硬币游戏
    [JSOI2010]满汉全席
    学大伟业 2017 国庆 Day1
  • 原文地址:https://www.cnblogs.com/CherryTab/p/11923319.html
Copyright © 2011-2022 走看看