Если класс содержит анонимный блок, имеющий system.out.println (); [Дубликат]

Добавление моих двух центов здесь - всегда по возможности используйте implements Runnable. Ниже приведены два оговорки о том, почему вы не должны использовать extends Thread s

  1. В идеале вы никогда не должны расширять класс Thread; класс Thread должен быть сделан final. По крайней мере, такие методы, как thread.getId(). См. это обсуждение для ошибки, связанной с расширением Thread s.
  2. Те, кто любит решать головоломки, могут видеть другой побочный эффект расширения Thread. Приведенный ниже код будет печатать недостижимый код, когда никто не уведомляет их.

См. http://pastebin.com/BjKNNs2G .

public class WaitPuzzle {

    public static void main(String[] args) throws InterruptedException {
        DoNothing doNothing = new DoNothing();
        new WaitForever(doNothing).start();
        new WaitForever(doNothing).start();
        new WaitForever(doNothing).start();
        Thread.sleep(100);
        doNothing.start();
        while(true) {
            Thread.sleep(10);
        }
    }


    static class WaitForever extends  Thread {

        private DoNothing doNothing;

        public WaitForever(DoNothing doNothing) {
            this.doNothing =  doNothing;
        }

        @Override
        public void run() {
            synchronized (doNothing) {
                try {
                    doNothing.wait(); // will wait forever here as nobody notifies here
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Unreachable Code");
            }
        }
    }

    static class DoNothing extends Thread {

        @Override
        public void run() {
            System.out.println("Do Nothing ");
        }
    } 
}

70
задан ryanyuyu 19 August 2016 в 13:04
поделиться

10 ответов

Я изучаю визуально, так что вот визуальное представление порядка, как SSCCE:

public class Example {

  static {
    step(1);
  }

  public static int step_1 = step(2);
  public int step_6 = step(6);

  public Example() {
    step(8);
  }

  {
    step(7);
  }

  // Just for demonstration purposes:
  public static int step(int step) {
    System.out.println("Step " + step);
    return step;
  }
}

public class ExampleSubclass extends Example {

  {
    step(9);
  }

  public static int step_3 = step(3);
  public int step_10 = step(10);

  static {
    step(4);
  }

  public ExampleSubclass() {
    step(11);
  }

  public static void main(String[] args) {
    step(5);
    new ExampleSubclass();
    step(12);
  }
}

Это печатает:

Step 1
Step 2
Step 3
Step 4
Step 5
Step 6
Step 7
Step 8
Step 9
Step 10
Step 11
Step 12

Имейте в виду, что порядок static детали; обратите внимание на разницу между порядком Example 's static и ExampleSubclass.

Также обратите внимание, что блок инициализации экземпляра всегда выполняется перед конструктором независимо от порядка , Однако порядок имеет значение между блоком инициализации и инициализатором поля.

34
ответ дан Ben Leggiero 18 August 2018 в 00:01
поделиться
  • 1
    шел через что SSCCE от вас комментировать. Интересно! – lft93ryt 27 January 2017 в 17:30
  • 2
    @ lft93ryt Надеюсь, это помогло: D – Ben Leggiero 28 January 2017 в 18:04
  • 3
    @ cricket_007 Хорошая мысль! Затем он идет 2, 1, 4, 3, 5, 6, 7, 8, 9, 10. Замечу, что в своем ответе – Ben Leggiero 18 December 2017 в 00:51
  • 4
    Просьба сопровождать любые нисходящие потоки по какой-то причине, поэтому я знаю, как лучше писать ответы в будущем :) – Ben Leggiero 3 February 2018 в 00:20

Загрузите только первый класс (комментируйте предложение extend), чтобы увидеть простой поток.

second - перейти к Блок статического блока против блока инициализации в Java? & amp; прочитайте принятый ответ там.

Редактирование:

  1. Выполнение происходит по пути SIC - статический (не статический) Инициализатор & amp; Конструктор.
  2. (Нестационарный) Инициализатор копируется в каждый конструктор - В ТОП! (следовательно, строки 3/4/5/6)
  3. Прежде чем инициализировать класс, его прямой суперкласс должен быть инициализирован - http://docs.oracle.com/javase/specs/jls/ se7 / html / jls-12.html # jls-12.4 (сначала появляется родительский статический блок).
7
ответ дан Community 18 August 2018 в 00:01
поделиться
  • Статические блоки инициализации выполняются во время загрузки класса.
  • В иерархии классов порядок выполнения статических блоков инициализации начинается с класса верхнего уровня.
  • В классе порядок выполнения статического блока находится сверху вниз.
  • Выше правило применяется независимо от того, где статический блок присутствует в классе.

(В вашем коде сначала будут выполняться родительские статические блоки, а затем статические блоки дочернего класса.)

  • Блоки инициализации экземпляра будут выполнены после вызова super (); в конструкторе. Всегда super (); - это самый первый оператор в конструкторе по умолчанию.

В вашем коде при создании объекта Child:

  • Выполняется конструктор по умолчанию класса Child.
  • Он вызовет super (); конструктор.
  • Затем выполняется конструктор суперкласса.
  • Родительский класс выполнит свой super (); вызов.
  • После этого исполняются блоки init экземпляра в классе Parent (сверху вниз).
  • Затем выполняется код внутри конструктора (если есть).
  • Затем он вернется в класс Child и выполнит блоки init экземпляра класса Child.
  • Наконец, код в дочернем конструкторе выполняется (если существует).
2
ответ дан hofmeister 18 August 2018 в 00:01
поделиться

Было бы очень полезно выполнить процесс построения объекта с помощью пошагового отладчика, имея представление, в котором вы можете видеть, как ваш объект проходит через фазы. Я нашел это очень полезным для очистки перспективы с более высокой точки зрения. Eclipse может помочь вам в этом с его шагом отладчика в функцию.

2
ответ дан Mihai Savin 18 August 2018 в 00:01
поделиться

В игре существует несколько правил

  • . Статические блоки всегда запускаются до создания объекта, поэтому вы видите сообщения печати от обоих родителей и дочерних статических блоков
  • теперь, когда вы вызываете конструктор подкласса (дочерний элемент), этот конструктор неявно вызывает super(); перед выполнением собственного конструктора. Блок инициализации вступает в игру еще до вызова конструктора, поэтому его сначала называют. Итак, теперь ваш родитель создан, и программа может продолжить создание дочернего класса, который будет проходить тот же процесс.

Пояснения:

  1. Статический блок родителя выполняется первым, потому что он загружается первым, а статические блоки вызывается при загрузке класса.
40
ответ дан Noel Evans 18 August 2018 в 00:01
поделиться
  • 1
    почему статический блок родителя выполняется первым? Я запускаю дочерний класс – CKR666 24 October 2013 в 10:06
  • 2
    @ CKR666 Поскольку он загружен первым , а статические блоки вызывается при загрузке класса. – Maroun 24 October 2013 в 10:07
  • 3
    но я запускаю дочерний класс – CKR666 24 October 2013 в 10:22
  • 4
    @ CKR666 Родительский класс загружается первым. – Maroun 24 October 2013 в 10:28
  • 5
    потому что базовый класс для производного класса - это родительский класс, созданный вами – Ankush Bist 13 June 2016 в 07:38

Просто хотел поделиться своими выводами. Я прочитал в одном из ответов на другой поток, что статические блоки выполняются сначала перед статическими полями, что неверно. Это зависит от того, что на первом месте, статического поля или статического блока. Посмотрите ниже код.

  1. JVM ищет класс, который имеет public static void main (String args []), чтобы он мог загрузить этот класс.
  2. Затем он инициализирует статические поля этого класса (если они попадают перед статическими блоками). Эти поля могут вызывать статические методы этого класса. Если они вызовут статический метод этого класса, то этот метод будет обслуживаться. Если они вызывают статический метод другого класса, тогда статические поля или блоки этого класса (в зависимости от того, что на первом месте) сначала инициализируются, тогда этот вызов метода обслуживается.
  3. Затем он перемещается в статические блоки.
  4. Возврат к основному методу.
    class TestLab {
    static int method(String a) {
        System.out.println("in static method of TestLab" + " Coming from " + a);
        System.out.println("b is " + b);
        return 6;
    }
    
    static int a = method("Line 11");
    static int b = 7;
    
    TestLab() {
        System.out.println("Inside test lab constructor");
    }
    
    static {
        System.out.println("In static block of TestLab");
    }
    
    }
    
    public class Test1 {
    public static void main(String[] args) {
        System.out.println("inside main method of Test 1");
        int a = TestLab.method("Line 26");
    }
    
    // static Test ref=new Test();
    Test1() {
        System.out.println("Default Constructor of Test1");
    }
    
    {
        System.out.println("In instance block of Test1");
    }
    static int d = TestLab.method("Line 37");
    static int e = methodOfTest1();
    static {
        System.out.println("In Static Block of Test1");
    }
    
    static int methodOfTest1() {
        System.out.println("inside static method:mehtodOfTest1()");
        return 3;
    }
    }
    

Вот результат:

in static method of TestLab Coming from Line 11
b is 0
In static block of TestLab
in static method of TestLab Coming from Line 37
b is 7
inside static method:mehtodOfTest1()
In Static Block of Test1
inside main method of Test 1
in static method of TestLab Coming from Line 26
b is 7
2
ответ дан pragun 18 August 2018 в 00:01
поделиться

поток управления -

статический блок -> блок инициализации -> и, наконец, конструктор.

static block -> Этот статический блок будет выполняться только один раз, когда появится управление к классу. (JVM Загрузить этот класс)

Блок инициализации -> Этот блок инициализации будет выполняться всякий раз, когда новый объект создан для класса (он будет выполнен из второго оператора конструктора затем следующие инструкции конструктора - помните, что первая инструкция конструктора будет супер () / this ())

Constructor -> Это будет получаться всякий раз, когда создается новый объект.

0
ответ дан Prakash VL 18 August 2018 в 00:01
поделиться

Вот что я нашел во время подготовки к сертификации.

Пока мы запускаем класс, происходит первая статическая блоки / статическая переменная. Если есть несколько статических блоков, он выполнит его в том порядке, в котором он появится,

Затем он выполнит инициализацию блоков / инициализацию переменной экземпляра. Если существует несколько инициализаций инициализации / инициализации переменных, она будет выполняться он в том порядке, в котором он появляется,

. Затем он будет смотреть на конструктор.

2
ответ дан PRAVEEN PS 18 August 2018 в 00:01
поделиться

Статический блок в java выполняется перед основным методом. Если объявить статический блок в классе java, он выполняется, когда класс загружается. Это инициализируется статическими переменными. Он в основном используется в JDBC. Статический блок в java выполняется каждый раз, когда класс загружается. Это также известно как статический блок инициализации. Статический блок в java инициализирует загрузку класса в память, это означает, что JVM читает байтовый код. Инициализация может быть любой; это может быть переменная инициализация или что-либо еще, что должно быть разделено всеми объектами этого класса. Статический блок - это нормальный блок кода, заключенный в фигурные скобки {}, которому предшествует статическое ключевое слово.

, поэтому статический блок выполняется первым.

Блоки инициализации экземпляра: выполняется каждый раз, когда экземпляр класса.

, поэтому следующий блок инициализации, выполняемый при создании экземпляра класса.

, затем выполнен конструктор

4
ответ дан rohan kamat 18 August 2018 в 00:01
поделиться
  • 1
    почему статический блок родительского класса выполняется сначала ....? Я сначала загружаю дочерний класс? – CKR666 24 October 2013 в 10:19
  • 2
    @ CKR666 - см. Мои обновления ниже! – Raúl 24 October 2013 в 14:54

Статический блок запускается, когда класс загружается в JVM. Хотя блок init копируется в конструктор, объект которого будет создан и запускается до создания объекта.

0
ответ дан Sunil Kumar Jha 18 August 2018 в 00:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: