Какие ограничения есть у локальных классов?

Вначале вспомним что такое локальный класс. Это класс, описанный в блоке кода, то есть, по-простому — между кавычек {}. Наиболее часто эти кавычки являются телом метода. Но могут они быть и просто блоком, статическим блоком, телом if-ов, циклов и т.д.
Локальный класс наделён особенностями внутренних классов, но имеет отличительные черты, а именно:
1)он имеет доступ только к финальным полям и аргументам обрамляющего метода, а также ко всем полям обрамляющего класса, в том числе приватным и статическим;
2)локальный класс виден и может создаваться только в блоке, в котором описан;

3)у локального класса не ставиться модификатор доступа;
4)не может иметь статических полей, методов, классов (за исключением финальных);
5)локальный класс, объявленный в статическом блоке может обращаться только к статическим полям внешнего класса.

 

Но! Начиная с Java8 мы можем обращаться в локальных классах к не финальным локальным переменным, если они не были изменены до момента инициализации класса. Также теперь стало возможным обращение к не финальным параметрам метода.

 

Может ли анонимный внутренний класс содержать статические методы?

Нет. У Анонимных внутренних классов, как и у внутренних классов не может быть статических полей, методов. Это вам подтвердит IDE, если вы попытаетесь запустить в ней код ниже.

 

Можно ли создать объект внутреннего класса, если у внешнего класса только private конструктор?

Имея подобный код

Напрямую, в другом классе (вне обрамляющего), конечно, создать объект InnerClass следующим способом не получится:

Но! Что если у нас есть метод, возвращающий экземпляр PrivateConst:

В этом случае приватный конструктор нам не помеха для создания объекта InnerClass. Так же мы без проблем сможем создавать его в методах и в других внутренних классах, принадлежащих PrivateConst. Ответ — можно, если каким-либо способом нам удастся получить объект обрамляющего класса.

Так же можно по хардкору пройтись рефлексией, выдернуть скрытый коструктор и уже с его помощью добыть объект класса. Попахивает изнасилованием, но работает.

 

Во что компилируются анонимные внутренние классы?​

Анонимные внутренние классы компилируются в файлы внешнийКласс$n.class. На месте внешнего класса, соответственно, название обрамляющего класса, внутри которого описывается анонимный внутренний класс. На месте n число от 1 до количества анонимных классов. Всё станет понятно когда Вы скомпилируете код и проследите за компиляцией файлов в директории проекта. ​

 

Чем отличаются анонимные классы созданные на основе интерфейса и на основе класса? Можно ли создать анонимный статический вложенный класс?​

Каких то преимуществ в выборе способа создания анонимного класса при реализации интерфейса или же наследовании от другого класса мы не получаем. Отталкиваться следует от начальной задачи. Если при обычной реализации интерфейса нам доступно неограниченное количество, которое мы можем объявить в списке имплементируемых, то при создании анонимного класса данное преимущество утрачивается, так как нам становится доступен лишь один интерфейс. Конечно можно где-то в другом месте унаследовать нужный нам интерфейс от множества других и в итоге создать на его основе анонимный класс… но это же можно сделать и с наследованием классов. Так что отличия анонимного класса созданного на основе интерфейса от созданного на основе класса такие же как и у обычных классов… методы реализуются/перегружаются и т.п.
Анонимный класс является статическим(не статическим) в зависимости от того находится ли он в статическом (не статическом) блоке кода или нет.

Можно ли создавать статические методы/переменные во внутреннем классе?​ Назовите три любых внутренних класса? Как внутренние классы решают проблему множественного наследования в java?​

Статические методы/переменные объявлять во внутреннем классе (не вложенном) нельзя. Внутренние классы можно встретить во всей библиотеке java core, private static class Holder —вложенный класс HashMap из java.util, в интерфейсе Map есть interface Entry<K,V>, который опять же в HashMap и реализуется в другом вложенном классе static class Entry<K,V> implements Map.Entry<K,V>. Открываем исходники обёрток и в Integer натыкаемся на private static class IntegerCache. И так далее… Ещё одним плюсом внутренних классов — является частичное решение проблемы множественного наследования, которое запрещено в java. Если классу А необходимо использовать protected методы класса B и C, то можно от класса В унаследоваться, а внутри себя объявить класс D, который будет наследником С. Таким образом у класса А появится доступ к желаемым методам в обход удовлетворения связи «является».

Какие бывают внутренние классы? Как правильно создавать объект вложенного класса? Как правильно создавать объект внутреннего класса? Зачем использовать ключевое слово final при создании анонимных классов? Во что компилируется анонимный внутренний класс?​

Внутренние классы бывают следующих типов:
-вложенные (статические) внутренние классы;
-внутренние классы члены;
-локальные классы;
-анонимные классы.

Вложенные статические классы.​

Имеют доступ только к статическим полям и методам содержащего их класса. Для создания экземпляра не требуется объект внешнего класса.

Вложенные статические классы в основном используются для группировки. Пример из кода компилируется в два класса OuterClass$InnerStaticClass.class и OuterClass.class.

Внутренние классы члены.​

Данному виду внутренних классов требуется экземпляр внешнего класса. Он имеет доступ ко всем полям и методам экземпляра внешнего класса, в том числе приватным. Также он может обращаться к статическим методам и полям обрамляющего класса.

Во внутренних классах-членах нельзя объявлять статические поля, статические методы и перечисления.

Локальные классы.​

Локальные классы создаются в блоках инициализации и в статических блоках java кода. Но чаще всего они используются внутри методов. Они могут обращаться только к финальным полям обрамляющего класса и аргументам метода. Его нельзя создать за пределами блока кода, в котором он описан. Локальный класс не может быть private, public, protected или static.

Анонимные классы.​

Анонимные классы используются в месте их создания. Они не имеют имени. Являясь частным случаем локального класса они приемствуют все ограничения локальных классов. Также могут обращаться к финальным локальным переменным внешнего класса и ко всем полям обрамляющего класса. Локальные переменные должны быть финальными для того, что бы пользователь класса был уверен в том, что пока он работает с данными они не изменятся во внешнем коде, что их состояние остаётся актуальным на всём протяжении жизни анонимного класса.

После компиляции анонимный класс из примера выше выглядит как TestAnonimClass$1.class, но в программе мы не можем обратиться к нему по такому имени.

Как преобразовать число в шестнадцатеричную строку? Как преобразовать число в двоичную строку?​

И вновь на помощь приходят классы обёртки, в которых заботливыми разработчиками уже реализованы методы для представления чисел в разных системах счисления. Пример:

 

Как узнать максимальное значение int? Как узнать минимальное значение byte?​

У классов обёрток в Java есть константы, возвращающие максимальные и минимальные значения обёртываемых примитивов.

 

Зачем в «ArrayList» нужно писать «?»​

Если дословно, не вдаваясь в термины дженериков, то данную конструкцию можно описать как ArrayList каких то типов, которые станут известны только в момент выполнения программы. «?» является так называемым групповым типом(маской), он не позволяет вызывать методы, модифицирующие дженеризированный объект. Но можно расширять маску и тогда методы становятся доступны. Пример в коде ниже:

Если раскомментировать лист строк, то пример не скомпилируется. Гораздо лучше отловить ошибку компилятором, нежели она всплывёт в момент выполнения программы.