2016-09-17 6 views
1

Недавно я прочитал this article автор Jake Wharton. Это нацелено на Android, но также отлично подходит для java, я думаю.Видимость методов и их стоимость

Рассмотрим следующий код:

public class A { 

    private String someField = "abc"; 

    class B { 

     public void doSomething() { 
      System.out.println(someField); 
     } 

    } 
} 

У нас есть простой класс А и внутренний класс B (Это есть ссылка на А и может ее членов Гости могут воспользоваться). Класс B получает доступ к полю someField в A, хотя он является частным. Согласно статье, это делается компилятором, генерирующим synthetic accessor methods, которые позволяют внутреннему классу получить доступ к полю.
Теперь мой путь более простой вопрос: почему компилятор даже заботится о visiblities при компиляции кода? Как мы видели в этом примере, создается новый метод, который в основном просто вводит служебные данные.
Визуальности - отличная вещь для архивирования хорошего программного обеспечения, но если компилятор сделан, проверяя, что все правильно в соответствии с объявленными видимостями, почему бы не оптимизировать эти методы (например, просто забирать все, чтобы быть общедоступным и разрешать ему звонки)?
Сначала я думал, что это связано с соображениями безопасности, но отражение позволяет получить доступ ко всем полям, не заботясь о видимости, насколько я знаю.

Это может быть основное недоразумение, если так, я был бы счастлив, если бы кто-нибудь мог объяснить это мне.

+1

«Почему компилятор даже заботится о видимости при компиляции кода?» Ну, все, что проверяет код, скорее всего, будет заботиться, с одной стороны ... конечно, компилятор JIT находится в гораздо лучшем месте, чтобы встроить вызовы методов, но это другое дело. (Обратите внимание, что отражение может быть отключено с помощью диспетчера безопасности - и это принудительно выполняется во время * выполнения *. Вы действительно не хотите, чтобы компилятор выдавал код, который будет терпеть неудачу в некоторых средах ...) –

ответ

3

Почему компилятор даже заботится о видимости при компиляции кода?

JVM не разрешает доступ к private методам/конструкторам/полям вне класса. У него нет специального правила для вложенных классов, которые были добавлены после создания этого правила. Вместо этого компилятор добавляет методы доступа, поэтому язык может поддерживать средства доступа к JVM.

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

Только в том случае, если метод не называется очень и не оптимизирован.

Добавление любого простого метода (On Hotspot, любой метод 35 байт или меньше) будут встраиваемыми очень быстро и не оказывает никакого влияния на производительность (за исключением, если будет достигнут максимальный уровень рядный)

почему бы не оптимизировать эти методы отсутствуют

Он делает это во время выполнения, чтобы предыдущие правила продолжали применяться.

отражение позволяет получить доступ ко всем областям, не заботясь о видимости, насколько я знаю.

Хотя не по умолчанию, вы должны явно указать это как параметр и не иметь SecurityManager, который его предотвращает.

0

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

Есть некоторые инструменты для оптимизации этого. В Android есть инструмент с именем ProGuard, который преобразует весь getter/setter в прямой доступ к полям.