Показаны сообщения с ярлыком static methods. Показать все сообщения
Показаны сообщения с ярлыком static methods. Показать все сообщения

пятница, 20 июня 2014 г.

Инициализация статических блоков. Хитрожопый пример.

Что будет выведено при выполнении данного кода?
class A {
    static {
        System.out.print("A");
    }
}
 
class B extends A {
    public static int b = 2;
 
    static {
        System.out.print("B");
    }
}
 
class C extends B {
    static {
        System.out.print("C");
        System.exit(0);
    }
}
 
public class StaticInitTest {
    public static void main(String[] args) {
        System.out.println(C.b);
    }
}
Ожидаемым ответом было ABC: C extends B, B extends A; значит, инициализируем статические блоки A, B, C, где и попадаем на System.exit(0).
Но это не так. Класс C не будет загружен вообще. Потому что:
 - не создавался объект класса С
 - не вызывались его статические методы
 - не было обращения к его статическим полям
А как же System.out.println(C.b)?
У класса С нет своих статических полей. Поле b принадлежит классу B, а не C, в этом и фокус. Класс B будет загружен, а к классу C (вопреки интуиции=)) обращения не было, его static блок выполнен не будет.
Правильный ответ - AB2.

P.S. Вопрос взят у Seregs12324 :: quizful.net

вторник, 10 июня 2014 г.

Java 8. Interfaces. Default methods. Static methods in interfaces.

В  Java 8 появилась возможность добавлять в интерфейсы не только абстрактные, но и содержащие реализацию методы.
interface Informative {
    default void tellAboutYourself() {
        System.out.println("I am " + getClass().getCanonicalName());
    }
}
 
class Board implements Informative{
    public static void main(String[] args) {
        new Board().tellAboutYourself();
    }
}
Output:
I am Board

Возможная польза от использования дефолтных методов:
  • Можно расширять существующие интерфейсы, не трогая их реализации
  • Функционал, общий для потомков, можно вынести в интерфейс
Однако, если класс реализует несколько интерфейсов с одноименными методами, хотя бы один из которых - дефолтный, то в этом классе придется переопределять метод.
interface Informative {
    default void tellAboutYourself() {
        System.out.println("I am " + getClass());
    }
}
interface Communicable {
    default void tellAboutYourself() {
        System.out.println("My name is " + getClass());
    }
} 
class Board implements Informative, Communicable {
    //compile error:
    //class Board inherits unrelated defaults for tellAboutYourself()
    // from types Informative and Communicable
}
interface Informative {
    default void tellAboutYourself() {
        System.out.println("I am " + getClass());
    }
}
interface Communicable {
    void tellAboutYourself();
}
class Board implements Informative, Communicable {
    //compile error:
    // Board is not abstract and does not override 
    // abstract method tellAboutYourself() in Communicable    
}

Зато при переопределении можно вызвать методы всех родительских интерфейсов.

interface Communicable {
    default void tellAboutYourself() {
        System.out.println("I am Communicable interface");
    }
}
 
interface Informative {
    default void tellAboutYourself() {
        System.out.println("I am Informative interface");
    }
}
 
class Board implements Informative , Communicable{
    @Override
    public void tellAboutYourself() {
        Informative.super.tellAboutYourself();
        Communicable.super.tellAboutYourself();
        System.out.println("My name is Board");
    }
}
У статических методов интерфейсов я нашла только одно отличие от статических методов классов: их нельзя вызвать через объект:
interface Informative {
    static void tellAboutYourself() {
        System.out.println("I am Informative interface");
    }
}
class Board implements Informative {
    public static void main(String[] args) {
        Informative informative = new Board();
        informative.tellAboutYourself();       //illegal static 
        // interface method call. The receiver expression 
        // should be replaced with the type qualifier 'Informative'
    }
}
class Board {
    public static void tellAboutYourself() {
        System.out.println("I am Board class");
    }
}
 
class BillBoard extends Board {
    public static void main(String[] args) {
        new BillBoard().tellAboutYourself();
    }
}
А вообще - хорошие штуки добавили, чо.