Скрытые особенности Java

Прочитав Hidden Features of C #, я подумал: «Каковы некоторые скрытые возможности Java?

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

ThreadLocals обычно не так широко известны, как способ хранения состояния в streamе.

Поскольку JDK 1.5 Java имеет чрезвычайно хорошо реализованные и надежные средства параллелизма, помимо просто блокировок, они живут в java.util.concurrent, и особенно интересным примером является подпакет java.util.concurrent.atomic, который содержит поточно-безопасные примитивы, которые реализуют сравнение -and-swap и может отображать фактические версии поддерживаемых аппаратных версий этих операций.

Объединенный союз в дисперсии параметра типа:

public class Baz {} 

Например, если вы хотите взять параметр, который является одновременно и Comparable, и Collection:

 public static  & Comparable> boolean foo(B b1, B b2, A a) { return (b1.compareTo(b2) == 0) || b1.contains(a) || b2.contains(a); } 

Этот искусственный метод возвращает true, если две заданные коллекции равны или если один из них содержит данный элемент, в противном случае – false. Следует отметить, что вы можете вызывать методы как Comparable, так и Collection для аргументов b1 и b2.

На днях я был удивлен, например, инициализаторами. Я удалял некоторые сложенные кодом методы и в итоге создал несколько инициализаторов экземпляров:

 public class App { public App(String name) { System.out.println(name + "'s constructor called"); } static { System.out.println("static initializer called"); } { System.out.println("instance initializer called"); } static { System.out.println("static initializer2 called"); } { System.out.println("instance initializer2 called"); } public static void main( String[] args ) { new App("one"); new App("two"); } } 

Выполнение main метода отобразит:

 static initializer called static initializer2 called instance initializer called instance initializer2 called one's constructor called instance initializer called instance initializer2 called two's constructor called 

Я думаю, это было бы полезно, если бы у вас было несколько конструкторов и нужен общий код

Они также обеспечивают синтаксический сахар для инициализации ваших classов:

 List numbers = new ArrayList(){{ add(1); add(2); }}; Map codes = new HashMap(){{ put("1","one"); put("2","two"); }}; 

JDK 1.6_07 + содержит приложение под названием VisualVM (bin / jvisualvm.exe), которое является хорошим графическим интерфейсом поверх многих инструментов. Это кажется более полным, чем JConsole.

Классовые карты с Java 6.

 java -classpath ./lib/* so.Main 

Вместо

 java -classpath ./lib/log4j.jar:./lib/commons-codec.jar:./lib/commons-httpclient.jar:./lib/commons-collections.jar:./lib/myApp.jar so.Main 

См. http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html.

Для большинства людей я беру интервью для позиций разработчиков Java, помеченных блоками, очень удивительно. Вот пример:

 // code goes here getmeout:{ for (int i = 0; i < N; ++i) { for (int j = i; j < N; ++j) { for (int k = j; k < N; ++k) { //do something here break getmeout; } } } } 

Кто сказал, что goto в java - это просто ключевое слово? 🙂

Как насчет ковариантных типов возврата, которые были установлены с JDK 1.5? Он довольно слабо рекламируется, поскольку он является дополнением unsexy, но, как я понимаю, абсолютно необходимо, чтобы дженерики работали.

По сути, теперь компилятор позволяет подclassу сузить возвращаемый тип переопределенного метода как подclass возвращаемого типа исходного метода. Так что это разрешено:

 class Souper { Collection values() { ... } } class ThreadSafeSortedSub extends Souper { @Override ConcurrentSkipListSet values() { ... } } 

Вы можете вызвать метод values подclassа и получить отсортированный streamобезопасный Set String без приведения вниз в ConcurrentSkipListSet .

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

Вместо:

 if( null != aObject && aObject instanceof String ) { ... } 

просто используйте:

 if( aObject instanceof String ) { ... } 

Передача управления в конечном блоке исключает любое исключение. Следующий код не бросает RuntimeException – он потерян.

 public static void doSomething() { try { //Normally you would have code that doesn't explicitly appear //to throw exceptions so it would be harder to see the problem. throw new RuntimeException(); } finally { return; } } 

От http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html

Разрешить методы и конструкторы в enums удивили меня. Например:

 enum Cats { FELIX(2), SHEEBA(3), RUFUS(7); private int mAge; Cats(int age) { mAge = age; } public int getAge() { return mAge; } } 

У вас может даже быть «постоянное тело определенного classа», которое позволяет определенному значению enums переопределять методы.

Больше документации здесь .

Параметры типа для общих методов могут быть указаны явно следующим образом:

 Collections.emptyMap() 

Вы можете использовать enums для реализации интерфейса.

 public interface Room { public Room north(); public Room south(); public Room east(); public Room west(); } public enum Rooms implements Room { FIRST { public Room north() { return SECOND; } }, SECOND { public Room south() { return FIRST; } } public Room north() { return null; } public Room south() { return null; } public Room east() { return null; } public Room west() { return null; } } 

EDIT: Спустя годы ….

Я использую эту функцию здесь

 public enum AffinityStrategies implements AffinityStrategy { 

https://github.com/peter-lawrey/Java-Thread-Affinity/blob/master/src/main/java/vanilla/java/affinity/AffinityStrategies.java

Используя интерфейс, разработчики могут определять свои собственные страtagsи. Использование enum означает, что я могу определить коллекцию (из пяти), встроенную в нее.

Начиная с Java 1.5, Java теперь имеет более чистый синтаксис для написания функций переменной arity. Итак, вместо простого прохождения массива теперь вы можете сделать следующее

 public void foo(String... bars) { for (String bar: bars) System.out.println(bar); } 

бары автоматически преобразуются в массив указанного типа. Не огромная победа, но победа, тем не менее.

Мой любимый: сбрасывать все трассировки стека streamа до стандартного.

windows: CTRLПерерыв в окне java cmd / console

unix: kill -3 PID

Несколько человек отправили об инициализаторах экземпляра, вот для этого полезно:

 Map map = new HashMap() {{ put("a key", "a value"); put("another key", "another value"); }}; 

Является быстрым способом инициализации карт, если вы просто делаете что-то быстро и просто.

Или используя его для создания прототипа каретки быстрой развертки:

 JFrame frame = new JFrame(); JPanel panel = new JPanel(); panel.add( new JLabel("Hey there"){{ setBackground(Color.black); setForeground( Color.white); }}); panel.add( new JButton("Ok"){{ addActionListener( new ActionListener(){ public void actionPerformed( ActionEvent ae ){ System.out.println("Button pushed"); } }); }}); frame.add( panel ); 

Конечно, это можно злоупотреблять:

  JFrame frame = new JFrame(){{ add( new JPanel(){{ add( new JLabel("Hey there"){{ setBackground(Color.black); setForeground( Color.white); }}); add( new JButton("Ok"){{ addActionListener( new ActionListener(){ public void actionPerformed( ActionEvent ae ){ System.out.println("Button pushed"); } }); }}); }}); }}; 

Динамические прокси (добавленные в 1.3) позволяют вам определить новый тип во время выполнения, соответствующий интерфейсу. Это пригодилось удивительное количество раз.

окончательная инициализация может быть отложена.

Он гарантирует, что даже при наличии сложного streamа логических значений всегда задаются значения. Слишком легко пропустить случай и вернуть нуль случайно. Это не делает возrotation невозможным, просто очевидно, что это специально:

 public Object getElementAt(int index) { final Object element; if (index == 0) { element = "Result 1"; } else if (index == 1) { element = "Result 2"; } else { element = "Result 3"; } return element; } 

Я думаю, что другая «пропущенная» особенность java – это сама JVM. Вероятно, это лучшая виртуальная машина. И он поддерживает множество интересных и полезных языков (Jython, JRuby, Scala, Groovy). Все эти языки могут легко и легко взаимодействовать.

Если вы создаете новый язык (например, в scala-case), вы сразу же получаете все существующие библиотеки, и поэтому ваш язык «очень полезен» с самого начала.

Все эти языки используют оптимизацию HotSpot. VM очень хорошо контролирует и отлаживает.

Вы можете определить анонимный подclass и напрямую вызвать метод на нем, даже если он не реализует никаких интерфейсов.

 new Object() { void foo(String s) { System.out.println(s); } }.foo("Hello"); 

Метод asList в java.util.Arrays позволяет легко сочетать varargs, общие методы и autoboxing:

 List ints = Arrays.asList(1,2,3); 

Использование этого ключевого слова для доступа к полям / методам, содержащим class из внутреннего classа. В приведенном ниже примере, скорее надуманном, мы хотим использовать class sortAscending classа контейнера из анонимного внутреннего classа. Использование ContainerClass.this.sortAscending вместо this.sortAscending делает трюк.

 import java.util.Comparator; public class ContainerClass { boolean sortAscending; public Comparator createComparator(final boolean sortAscending){ Comparator comparator = new Comparator() { public int compare(Integer o1, Integer o2) { if (sortAscending || ContainerClass.this.sortAscending) { return o1 - o2; } else { return o2 - o1; } } }; return comparator; } } 

Не совсем особенность, но забавный трюк, который я недавно обнаружил на какой-то веб-странице:

 class Example { public static void main(String[] args) { System.out.println("Hello World!"); http://Phi.Lho.free.fr System.exit(0); } } 

является допустимой программой Java (хотя она генерирует предупреждение). Если вы не видите, почему, см. Ответ Грегори! 😉 Ну, подсветка синтаксиса здесь также дает подсказку!

Это не совсем «скрытые функции» и не очень полезны, но в некоторых случаях могут быть чрезвычайно интересными:
Класс sun.misc.Unsafe – позволит вам реализовать прямое управление памятью на Java (вы можете даже написать самомодифицирующийся Java-код с этим, если вы попробуете много):

 public class UnsafeUtil { public static Unsafe unsafe; private static long fieldOffset; private static UnsafeUtil instance = new UnsafeUtil(); private Object obj; static { try { Field f = Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); unsafe = (Unsafe)f.get(null); fieldOffset = unsafe.objectFieldOffset(UnsafeUtil.class.getDeclaredField("obj")); } catch (Exception e) { throw new RuntimeException(e); } }; } 

При работе в Swing мне нравится скрытая функция Ctrl- Shift- F1 .

Он выгружает дерево компонентов текущего windows.
(Предполагая, что вы не привязали это нажатие к чему-то еще.)

Каждый файл classа начинается с шестнадцатеричного значения 0xCAFEBABE, чтобы идентифицировать его как действительный байт-код JVM.

( Объяснение )

Мой голос идет на java.util.concurrent с его параллельными коллекциями и гибкими исполнителями, позволяющими, среди прочего, пулы streamов, запланированные задачи и скоординированные задачи. DelayQueue – мой личный фаворит, где элементы становятся доступными после определенной задержки.

java.util.Timer и TimerTask можно безопасно отложить.

Кроме того, не совсем скрытые, но в другом пакете от других classов, связанных с датой и временем. java.util.concurrent.TimeUnit полезен при преобразовании между наносекундами, микросекундами, миллисекундами и секундами.

Он читает намного лучше, чем обычный someValue * 1000 или someValue / 1000.

Ключевое слово assert уровня языка.

На самом деле это не часть языка Java, но дизассемблер javap, который поставляется с JDK Sun, широко не известен и не используется.

Добавление конструкции для каждого цикла в 1.5. Я <3 это.

 // For each Object, instantiated as foo, in myCollection for(Object foo: myCollection) { System.out.println(foo.toString()); } 

И может использоваться во вложенных экземплярах:

 for (Suit suit : suits) for (Rank rank : ranks) sortedDeck.add(new Card(suit, rank)); 

Конструкция for-each также применима к массивам, где она скрывает индексную переменную, а не iterator. Следующий метод возвращает сумму значений в массиве int:

 // Returns the sum of the elements of a int sum(int[] a) { int result = 0; for (int i : a) result += i; return result; } 

Ссылка на документацию Sun

я лично обнаружил java.lang.Void очень поздно – улучшает читаемость кода в сочетании с дженериками, например Callable

  • Доступ к переменной осуществляется внутри внутреннего classа. Нужно быть объявленным окончательным
  • свойство системы настройки
  • Android HTML.fromHTML () с изображениями?
  • Android Horizontal LinearLayout - Элементы обертки
  • Как получить данные из каждого динамически созданного EditText в Android?
  • Как поймать особые исключения Firebase Auth
  • java.lang.numberformatexception: недействительный double: ""
  • Сегодня n-й день года
  • Что такое Runtime.getRuntime (). TotalMemory () и freeMemory ()?
  • "'Void' type not allowed here" error (Java)
  • размещение файла в пути к classам
  • Давайте будем гением компьютера.