В чем различие между использованием оператора instanceof и Class.isAssignableFrom(…) метода?

Этим вопросом я задавался не один раз при разработке кода, определяющего принадлежность определённого экземпляра класса к определённой иерархии наследования, а так же принадлежность к реализации определённого интерфейса. В Java существует несколько подходов к решению данной проблемы, из которых мы обратим внимание на различие между использованием оператора instanceof и Class.isAssignableFrom(Class<?> cls) метода. Одним из главных различий является то, что использование оператора instanceof позволяет выявлять ошибки на уровне компиляции кода. Пример кода, позволяющий выявить ошибку времени компиляции, приведён в Листинге 1.

Листинг 1. Некорректное использование оператора instanceof

if(String.class instanceof Integer) {
    System.out.println("true");
}

В то время как код, приведённый в Листинге 2, в конечном итоге будет выполнен без каких-либо ошибок.

Листинг 2. Использование метода Class.isAssignableFrom(Class<?> cls)

if(Integer.class.isAssignableFrom(String.class)) {
    System.out.println("true");
}

Итак, использование оператора instanceof имеет место тогда, когда Вы четко знаете, в какой иерархии наследования участвует класс и какие интерфейсы он реализует, в противном случае целесообразно посмотреть в сторону Class.isAssignableFrom(Class<?> cls) метода, использование которого в свою очередь позволяет реализовать более гибкий код, предоставляющий возможность композиции.

Cloud Computing

Что вы знаете об облачном вычислении? Ничего кроме жаргона? Тогда этот пост именно для Вас! Sun анонсировала отличный фришный гайд об облачном вычислении, ознакомившись с которым вы узнаете:

  • Определение облачного вычисления и его приемущества
  • Различия между публичными, приватными и гибридными облаками
  • Детали технологий виртуализации
  • и др.

Ссылка для скачивания: Cloud Computing

Java Reflection: работа с приватными полями и методами

Используя механизм рефлексии в Java, клиент получает широкие возможности как для извлечения значений из инкапсулированных полей класса, так и для получения значений, возвращаемых инкапсулированными методами класса.

Работа с приватными полями

Для получения доступа к приватным полям класса, прежде всего необходимо получить экземпляр класса java.lang.reflect.Field. Для этого нужно воспользоваться Class.getDeclaredField(String name) либо Class.getDeclaredFields() методами класса Class. Обратите внимание на то, что методы Сlass.getField(String name) и Class.getFields() предоставляют доступ только к полям, объявленных с  модификатором доступа public. Из этого следует, что они не предоставляют возможности для получения полей, объявленных с модификаторами доступа protected и private.

Рассмотрим более детально доступ к приватным полям класса на примерах, приведённых в Листингах 1 и 2.

Листинг 1. Класс PrivateObject

public class PrivateObject {

  private String privateString = null;

  public PrivateObject(String privateString) {
    this.privateString = privateString;
  }
}

Листинг 2. Реализация доступа к приватному полю класса PrivateObject

PrivateObject privateObject = new PrivateObject("The Private Value");

Field privateStringField = PrivateObject.class.getDeclaredField("privateString");

privateStringField.setAccessible(true);

String fieldValue = (String) privateStringField.get(privateObject);
System.out.println("fieldValue = " + fieldValue);

При выполнении кода, приведённого в Листинге 2, на экран будет выведено сообщение “fieldValue = The Private Value”, содержащее значение приватного поля privateString класса PrivateObject. Обратите внимание на использование метода PrivateObject.class.getDeclaredField(”privateString”). Этот метод возвращает поле именно того класса, у которого непосредственно вызывается метод getDeclaredField(String name). Другими словами, этот метод не предоставляет доступ к полям, объявленных в суперклассах. Далее, вызывая метод setAccessible(true) у экземпляра privateStringField класса Field, вы тем самым предоставляете механизму рефлексии доступ к приватному полю privateString объекта privateStringField.

Работа с приватными методами

Для получения доступа к приватным методам класса, прежде всего необходимо получить экземпляр класса java.lang.reflect.Method. Для этого нужно воспользоваться Class.getDeclaredMethod(String name, Class[] parameterTypes) либо Class.getDeclaredMethods() методами класса Class. Заметьте, что методы Сlass.getMethod(String name) и Class.getMethods() предоставляют доступ только к методам, объявленных с модификатором доступа public. Из этого следует, что они не предоставляют возможности для получения методов, объявленных с модификаторами доступа protected и private.

Рассмотрим более детально доступ к приватным методам класса на примерах, приведённых в Листингах 3 и 4.

Листинг 3. Класс PrivateObject с приватным методом getPrivateString()

public class PrivateObject {

  private String privateString = null;

  public PrivateObject(String privateString) {
    this.privateString = privateString;
  }

  private String getPrivateString(){
    return this.privateString;
  }
}

Листинг 4. Реализация доступа к приватному методу класса PrivateObject

PrivateObject privateObject = new PrivateObject("The Private Value");

Method privateStringMethod = PrivateObject.class.getDeclaredMethod("getPrivateString", null);

privateStringMethod.setAccessible(true);

String returnValue = (String)
        privateStringMethod.invoke(privateObject, null);

System.out.println("returnValue = " + returnValue);

При выполнении кода, приведённого в Листинге 4, на экран будет выведено сообщение “returnValue = The Private Value”. Данное сообщение содержит значение “The Private Value”, возвращаемое методом getPrivateString(). Обратите внимание на использование метода PrivateObject.class.getDeclaredMethod(”getPrivateString”, null). Этот метод возвращает метод именно того класса, у которого непосредственно вызывается метод getDeclaredMethod(String name, Class[] parameterTypes). Другими словами, этот метод не предоставляет доступ к методам, объявленных в суперклассах. Далее, вызывая метод setAccessible(true) у экземпляра privateStringMethod класса Method, вы тем самым предоставляете механизму рефлексии доступ к приватному методу getPrivateString() объекта privateStringField.

Источник: http://tutorials.jenkov.com/