Як пов'язані метод
Припустимо, у нас є клас:
Так само цей метод можна застосовувати і до методів класу, і до полів класу. Код для поля виглядатиме так:
public native int getModifiers()із класу Classта деякі константи із класу Modifier.
Припустимо, у нас є клас:
public static abstract class NestedClass{
} Метод getModifiers()повертає результат у вигляді числа, в якому зашифровані модифікатори доступу того класу або методу, у якого він викликаний. Щоб викликати getModifiers()для класу, наприклад NestedClass, для створення об'єкта класу Classдля класу NestedClass. А вже на об'єкті класу Class<NestedClass>викликати getModifiers().
Class<NestedClass> c = NestedClass.class;
int classModifiers = c.getModifiers(); Або в один рядок і виведемо на екран результат та його двійкове уявлення:
int classModifiers = NestedClass.class.getModifiers();
System.out.printf("classModifier = %d%n",classModifiers);
System.out.printf("classModifier в двоичной системе счисления = %s%n",Integer.toBinaryString(classModifiers)); На екрані:
classModifiers = 1033
classModifiers в двоичной системе счисления = 10000001001 Добре, але чому саме це число? Давайте розбиратися на прикладі класу NestedClass. Допустимо, у нас є метод:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
}
У його параметри надходитимуть: int allModifiers = NestedClass.class.getModifiers(), як із прикладу вище. А int specificModifierдорівнюватиме якийсь із констант класу Modifier: Modifier.PUBLIC, Modifier.STATICі т.п. (Інші константи розглянемо нижче). І метод буде повертати нам trueякщо клас містить модифікатор доступу, переданий в specificModifier. Якщо ні – false. Код у тестовому класі виглядатиме так:
boolean isPublic = isModifierSet(classModifiers, Modifier.PUBLIC);
boolean isInterface = isModifierSet(classModifiers, Modifier.INTERFACE);
boolean isAbstract = isModifierSet(classModifiers, Modifier.ABSTRACT);
System.out.printf("\"Is NestedClass public?\" - %b%n", isPublic); //true
System.out.printf("\"Is NestedClass interface?\" - %b%n", isInterface); //false
System.out.printf("\"Is NestedClass abstract?\" - %b%n", isAbstract); //true Як же реалізувати логіку методу isModifierSet? Представимо у двійковій системі модифікатори в класі Modifier: (наприклад, Modifier.FINAL= 0x00000010, або в 10-й системі - 16. 16 у двійковій = 00010000)
Modifier.PUBLIC= 1 = 0000 0001Modifier.PRIVATE= 2 = 0000 0010Modifier.PROTECTED= 4 = 0000 0100Modifier.STATIC= 8 = 0000 1000Modifier.FINAL= 16 = 0001 0000Modifier.SYNCHRONIZED= 32 = 0010 0000Modifier.VOLATILE= 64 = 0100 0000Modifier.TRANSIENT= 128 = 1000 0000Modifier.NATIVE= 256 = 1 0000 0000Modifier.INTERFACE= 512 = 10 0000 0000Modifier.ABSTRACT= 1024 = 100 0000 0000NestedClass.class.getModifiers()= 1033 = 100 0000 1001
getModifiers()обчислюється в такий спосіб, що й клас містить певний модифікатор доступу, такий самий розряд, як й у модифікаторі доступу, стає рівним 1. У NestedClassтакі модифікатори доступа: public static abstract. В PUBLICодиниці дорівнює 0 розряд (крайній праворуч). В STATIC- 3. В ABSTRACT- 10. І тепер дивимося на наш NestedClass.class.getModifiers(): У 0, 3 та 10 розрядах у нього одиниця! А решта нуль. Далі переходимо до розв'язання задачі. Ми повинні зрозуміти, чи містить наш getModifiers()певний модифікатор. Розглянемо випадок для модифікатора final. Modifier.FINAL= 16 = 0001 0000, отже одиниці дорівнює 4 розряд. За аналогією з прикладом вище, дивимося, чи містить нашNestedClass.class.getModifiers()= 100 0000 1001 Modifier.FINAL. Тут 4 розряд дорівнює 0. Значить не містить, що відповідає дійсності ( NestedClassне final). Але яку логіку писати у методі? Потрібно застосувати логічне AND (&), яке дорівнює 1, якщо обидва біти дорівнюють 1. В інших випадках 0. Наш метод остаточно буде виглядати так:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
return (allModifiers & specificModifier) > 0;
} Переконаємося, що код працює і покажемо, чому він працює. Обчислюємо NestedClass.class.getModifiers() & Modifier.FINAL:
- 100 0000 1001 -
NestedClass.class.getModifiers() - 000 0001 0000 -
Modifier.FINAL(додали зліва 3 нуля для зручності) - 000 0000 0000 - відповідь 0. Ми не маємо жодної одиниці, т.к. тільки 1&1=1. 1&0=0, 0&1=0, 0&0=0;
returnповерне false, т.к. 0> 0 - false. Значить, такого модифікатора доступу немає. Дивимося Modifier.ABSTRACT & NestedClass.class.getModifiers():
- 100 0000 0000 -
Modifier.ABSTRACT - 100 0000 1001 -
NestedClass.class.getModifiers() - 100 0000 0000 - Збіглися крайні одиниці зліва. Перекладаємо в десяту: відповідь 1024.
returnповерне true, т.к. 1024 > 0 - true. Значить, такий модифікатор доступу є.
Так само цей метод можна застосовувати і до методів класу, і до полів класу. Код для поля виглядатиме так:
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class A {
private static transient volatile String name = "Bob";
public static void main(String[] args) throws NoSuchFieldException {
Field field = A.class.getDeclaredField("name");
int fieldModifiers = field.getModifiers();
boolean isPublic = isModifierSet(fieldModifiers, Modifier.PUBLIC);
boolean isFinal = isModifierSet(fieldModifiers, Modifier.FINAL);
boolean isVolatile = isModifierSet(fieldModifiers, Modifier.VOLATILE);
System.out.printf("\"Is A.name public?\" - %b%n", isPublic); //false
System.out.printf("\"Is A.name final?\" - %b%n", isFinal); //false
System.out.printf("\"Is A.name volatile?\" - %b%n", isVolatile); //true
}
public static boolean isModifierSet(int allModifiers, int specificModifier) {
return (allModifiers & specificModifier) > 0;
}
}
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ