2008-08-19 2 views

ответ

37

Языковой уровень Утверждение ключевое слово.

17

Мне очень нравится перезаписанный API Threading от Java 1.6. Вызываемые письма великолепны. Они в основном являются потоками с возвращаемым значением.

+0

По сравнению со старыми вещами просто – 2008-09-12 15:59:37

+0

Вызываемые символы - это Runnables с возвращаемым значением, а не с потоками. – Tom 2008-09-27 11:09:43

+0

Примеры, пожалуйста? – neu242 2008-10-22 07:03:36

25

статический импорт в «усилить» язык, так что вы можете сделать хорошие буквальные вещи типа безопасных способов:

List<String> ls = List("a", "b", "c"); 

(можно также сделать с картами, массивами, множествами).

http://gleichmann.wordpress.com/2008/01/13/building-your-own-literals-in-java-lists-and-arrays/

Принимая его дальше:

List<Map<String, String>> data = List(Map(o("name", "michael"), o("sex", "male"))); 
+0

Очень плохо, что этот тип функций не находится непосредственно в API коллекций. – 2008-10-07 12:36:32

+19

это не часть языка; автор в ссылке определяет метод «Список» для создания списка – kdgregory 2009-01-01 13:23:55

62

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

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

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

432

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

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

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

+0

Слишком плохо, что моя IDE (NetBeans) форматирует их ужасно, когда это автоматическое форматирование. – 2008-09-12 15:57:26

+40

Инициализация с двойной привязкой ... странно ... Я бы с осторожностью относился к этой особой идиоме слишком широко, потому что она фактически создает анонимный подкласс объекта, что может вызвать запутывающие проблемы равенства/hashcode. java.util.concurrent - действительно отличный пакет. – 2008-09-17 12:02:04

+6

Я * научил * Java, и это самый первый раз, когда я столкнулся с этим синтаксисом ..., который показывает, что вы никогда не прекращаете обучение = 8-) – Yuval 2008-09-23 08:48:05

15

Не действительно особенность, но это заставляет меня хихикать, что goto зарезервированное слово, которое не делает ничего, кроме побуждая JAVAC тыкать в глаза. Просто чтобы напомнить вам, что вы сейчас в OO-land.

+4

http://stackoverflow.com/questions/15496/hidden-features-of-java#answer-39433 :-) – Nivas 2009-01-27 20:56:55

23

Являясь стартером, я очень ценю программное обеспечение для мониторинга JConsole в Java 6, он уже решил пару проблем для меня, и я продолжаю находить для него новые возможности.

Очевидно, JConsole уже был на Java 5, но я считаю, что теперь он улучшен и, по крайней мере, работает намного стабильнее на данный момент.

JConsole в Java 5: JConsole in Java 5

JConsole в Java 6: JConsole in Java 6

И пока вы на него, иметь хороший взгляд на другие инструменты в серии: Java 6 troubleshooting tools

+1

JConsole будет заменен на VisualVM в будущих версиях (возможно, 6u10) – Tom 2008-09-27 11:10:52

+2

Конечно, JConsole будет заменен или, скорее, уточнен, уже с 6u7 я думаю. Но многие по-прежнему используют более старые версии Sun JVM и, следовательно, нуждаются в JConsole. Я до сих пор не нашел ничего, поддерживающего теорию о том, что JVisualVM будет поддерживать более старые версии JDK. – PPS 2008-10-14 14:04:38

12

Это не совсем скрыто, но отражение невероятно полезно и мощно. Целесообразно использовать простое Class.forName ("..."). NewInstance(), где тип класса настраивается. Легко написать такую ​​фабричную реализацию.

+1

Я использую отражение все время, чтобы делать такие вещи, как T [] filterItems (T []) , который вы можете позвонить с помощью items = filterItems (items); Определение метода немного уродливее, но это действительно упрощает чтение кода клиента. – 2008-09-17 14:12:35

144

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

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

class Souper { 
    Collection<String> values() { 
     ... 
    } 
} 

class ThreadSafeSortedSub extends Souper { 
    @Override 
    ConcurrentSkipListSet<String> values() { 
     ... 
    } 
} 

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

+0

Можете ли вы привести пример использования? – 2008-09-12 15:58:30

+24

Я использую это много. Клон() - отличный пример. Он должен возвращать Object, что означает, что вам следует сказать, например. (Список) list.clone(). Однако, если вы объявляете List clone() {...}, то бросок не нужен. – 2008-09-14 15:04:10

4

Функторы довольно крутые. Они довольно близки к указателю на функцию, который каждый, как правило, быстро говорит, что это невозможно в Java.

Functors in Java

+7

Невозможно, просто невозможно дословно. – 2009-02-04 16:11:04

156

Для большинства людей я интервью на позиции разработчика 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 это просто ключевое слово? :)

+1

Я бы почти надеялся, что люди не знают об этой функции. Гораздо предпочтительнее, чтобы они упорядочили свой код на более мелкие, более значимые методы и просто использовали `return`, в большинстве случаев. В настоящий момент существует большой фурор вокруг этой языковой конструкции, добавляемой к PHP6. – Cheekysoft 2008-09-07 15:28:45

+2

Ну, я предпочел бы иметь возможность сделать это несколькими способами. Например, я видел людей, использующих System.exit (1); в сервлете и EJB-коде, но это не значит, что мы должны удалить System.exit(); от JDK, правильно? – 2008-09-08 10:25:17

+1

Я согласен, что это должно быть разрешено на языке, даже если оно не используется часто. Я не могу вспомнить один экземпляр, когда я его использовал, но я видел обе стороны аргумента для его использования. Лучше иметь его и не использовать, чем нужно, и не иметь его. – martinatime 2008-09-16 20:41:32

13

Я знал, что Java 6 включает поддержку сценариев, но я только недавно обнаружил jrunscript, который может интерпретировать и запускать JavaScript (и, один предполагает, другие языки сценариев, такие как Groovy) в интерактивном режиме, вроде как Python shell или irb в Ruby

88

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

279

Совместное объединение в параметре типа дисперсии:

public class Baz<T extends Foo & Bar> {} 

Например, если вы хотите принять параметр, это и Сопоставимые и Коллекцию:

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

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

12

Я знаю, что это было добавлено в выпуске 1.5, но новый перечислительный тип - отличная возможность. Не использовать старый шаблон int enum очень помог куча моего кода. Check out JLS 8.9 для сладкого соуса на вашем картофеле!

+0

Большинство «старых школ» Java-парней никогда Постарайтесь начать использовать эту функцию, но я согласен, что это здорово. – 2008-09-12 16:01:06

11

финал переменного экземпляра:

Действительно полезный для многопоточной коды, и это делает его намного легче рассуждать о состоянии экземпляра и корректности. Не видели этого в отраслевом контексте и часто не рассматривали в Java-классах.


статическими {что-то}:

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

220

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

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 

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

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

List<Integer> numbers = new ArrayList<Integer>(){{ add(1); add(2); }}; 

Map<String,String> codes = new HashMap<String,String>(){{ 
    put("1","one"); 
    put("2","two"); 
}}; 
+0

Возможно, было бы более разборчивым иметь метод, который вызывали бы все ваши конструкторы, или чтобы все конструкторы вызывали корень этого (...) в отличие от супер (...) – 2008-09-18 12:16:26

+0

Хорошо знать, что проверили исключения, забрасываемые анонимными инициализаторами, должны быть объявлены конструкторами. Статические инициализаторы не могут выбрасывать проверенные исключения. – Tom 2008-09-27 11:09:05

+38

Преимущество этого в явном методе, который нужно вызвать, заключается в том, что, если кто-то добавляет конструктор позже, им не нужно помнить о вызове init(); это будет сделано автоматически. Это может предотвратить ошибки будущих программистов. – 2008-10-10 15:45:54

6

Джошуа Блох новый Effective Java - хороший ресурс.

+0

Великая книга, но на самом деле это не так много со скрытыми функциями. – 2008-10-16 12:35:30

134

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

enum Cats { 
    FELIX(2), SHEEBA(3), RUFUS(7); 

    private int mAge; 
    Cats(int age) { 
    mAge = age; 
    } 
    public int getAge() { 
    return mAge; 
    } 
} 

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

Дополнительная документация here.

+20

Действительно удивительная особенность на самом деле - делает перечисления OO и решает много проблем с инициализацией очень простым способом. – 2008-10-06 18:00:45

+0

Из-за этого перечислены также перечислимые числа. – Chii 2008-10-10 11:30:45

+5

Enum as singleton? Enum только с одним значением? – 2008-11-13 00:01:15

37

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

201

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

121

В Тип PARAMS для общих методов можно указать явно, как так:

Collections.<String,Integer>emptyMap() 
+10

И богом это уродливо и запутанно. И не относится к типу безопасности. – 2008-09-16 12:21:40

19

Потребовалось их достаточно долго, чтобы добавить поддержку для этого,

System Tray

56

Метод asList в java.util.Arrays позволяет хорошая комбинация варгаров, общих методов и автообношений:

List<Integer> ints = Arrays.asList(1,2,3); 
6

Некоторых приемов управления потоком, finally вокруг return заявления:

int getCount() { 
    try { return 1; } 
    finally { System.out.println("Bye!"); } 
} 

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

final int foo; 
if(...) 
    foo = 1; 
else 
    throw new Exception(); 
foo+1; 
7

JVisualVM из каталога bin в дистрибутиве JDK. Мониторинг и даже профилирование любого java-приложения, даже если вы не запускали никаких специальных параметров. Только в последних версиях Java 6SE JDK.

142

Передача управления в блоке finally исключает любое исключение. Следующий код не бросает 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

36

добавлением для каждой петли-конструкции в 1,5 раза. I < 3 it.

// 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)); 

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

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

Link to the Sun documentation

+30

Я думаю, что использование `i` здесь очень запутанно, так как большинство людей ожидают, что я буду индексом, а не элементом массива. – cdmckay 2009-02-23 07:28:53

+0

Итак ... int sum (int [] array) { int result = 0; for (int element: array) { результат + = элемент; } результат возврата; } – Drew 2009-03-10 23:27:37

10

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

int const = 1; // "not a statement" 
const int i = 1; // "illegal start of expression" 

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

+0

скрытая функция? как так? – 2008-10-17 13:17:55

+1

Не совсем «особенность», но определенно «скрытая». – 2008-10-17 20:13:41

52

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

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

    System.exit(0); 
    } 
} 

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

+4

Этот номер находится в Java Puzzlers. – cdmckay 2009-02-23 07:31:54

93

Мое избранное: сбрасывать все следы стека стека до стандартного.

окна: CTRL - Перерыв в ваших ява ЦМД/окно консоли

UNIX: kill -3 PID

+15

Также ctrl- \ in Unix. Или используйте jstack из JDK. – 2008-09-17 14:53:02

7

Сила вы можете иметь над сборщиком мусора, и как она управляет коллекцией объектов является очень мощным, особенно для долговременных и чувствительных к времени приложений. Он начинается со слабых, мягких и фантомных ссылок в пакете java.lang.ref. Взгляните на них, особенно для создания кешей (уже есть java.util.WeakHashMap). Теперь копайте немного глубже в ReferenceQueue, и вы начнете иметь еще больший контроль. Наконец, возьмите документы в сборщике мусора, и вы сможете контролировать, как часто он работает, размеры разных областей сбора и типы используемых алгоритмов (для Java 5 см. http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html).

53

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

import java.util.Comparator; 

public class ContainerClass { 
boolean sortAscending; 
public Comparator createComparator(final boolean sortAscending){ 
    Comparator comparator = new Comparator<Integer>() { 

     public int compare(Integer o1, Integer o2) { 
      if (sortAscending || ContainerClass.this.sortAscending) { 
       return o1 - o2; 
      } else { 
       return o2 - o1; 
      } 
     } 

    }; 
    return comparator; 
} 
} 
+4

Это необходимо, только если вы затеняли имя (в вашем случае, с именем параметра метода). Если вы вызывали аргумент что-то еще, тогда вы могли бы напрямую обращаться к переменной класса sortAscending класса Container, не используя «this». – 2009-02-04 17:12:12

+7

По-прежнему полезно иметь ссылку на охватывающий класс, например. если вам нужно передать его некоторому методу или конструктору. – PhiLho 2009-02-14 19:13:40

46

Это не совсем «скрытые возможности» и не очень полезно, но может быть очень интересно в некоторых случаях:
Class 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); 
     } 
    }; 
} 
+20

это солнце. API, который на самом деле не является частью языка Java – 2009-03-05 02:53:51

3

Поскольку никто еще не сказал, что это все же (я думаю), моя любимая функция Auto бокса!

public class Example 
{ 
    public static void main(String[] Args) 
    { 
     int a = 5; 
     Integer b = a; // Box! 
     System.out.println("A : " + a); 
     System.out.println("B : " + b); 
    } 
} 
+5

Я думаю, что речь идет о скрытых функциях, а не о любимых функциях. Я предполагаю, что автобоксинг хорошо известен всем, кто использует 1.5 или новее. – 2008-09-24 23:08:38

9

Как насчет свойств в вашем выборе кодировок? Раньше, когда вы загружали свои свойства, вы предоставили InputStream, а метод load() расшифровал его как ISO-8859-1. Вы могли фактически хранить файл в какой-либо другой кодировке, но вы должны были использовать отвратительный хак, как это после загрузки, чтобы правильно декодировать данные:

String realProp = new String(prop.getBytes("ISO-8859-1"), "UTF-8"); 

Но, как в JDK 1.6, есть load() метод, берет Reader вместо InputStream, что означает, что вы можете использовать правильную кодировку с самого начала (есть также метод store(), который берет Writer). Мне кажется, это очень важно для меня, но, похоже, он был проклят в JDK без фанфары. Я только наткнулся на это несколько недель назад, и быстрый поиск в Google показал только одно упоминание об этом.

26

Если вы много развития JavaBean и работы с поддержкой изменения свойств, вы вообще заводиться писать много сеттеров, как это:

public void setFoo(Foo aFoo){ 
    Foo old = this.foo; 
    this.foo = aFoo; 
    changeSupport.firePropertyChange("foo", old, aFoo); 
} 

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

public void setFoo(Foo aFoo){ 
    changeSupport.firePropertyChange("foo", this.foo, this.foo = aFoo); 
} 

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

+1

Является ли порядок выполнения аргументов корректным в Java? В противном случае это может создать беспорядок. – 2008-09-26 13:10:03

+0

Он хорошо определен, но не в целом хорошо понимается. Это будет технически работать, но явно запутанно. – 2008-09-26 14:40:12

+7

Да - порядок или исполнение аргументов чрезвычайно четко определены. Я не уверен, что я согласен с тем, что это более запутанно, чем наличие трех строк нежелательного кода в каждом наборе в каждом отдельном JavaBean - гораздо лучше сосредоточиться на коде, который вы хотите записать, вместо этого типа шаблона! – 2008-09-30 03:52:23

5

Строка с параметрическим классом.

Class.forName(className).newInstance(); 

нагрузки ресурс (свойство файла, XML, XSLT, изображения и т.д.) от развертывания банку файла.

this.getClass().getClassLoader().getResourceAsStream(...) ; 
9

Что-то, что меня действительно удивило, было обычным механизмом сериализации.

Хотя эти методы являются частным !!, они «таинственно», вызываемые JVM во время сериализации объектов.

private void writeObject(ObjectOutputStream out) throws IOException; 
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException; 

Таким образом, вы можете создать свои собственные сериализации, чтобы сделать его более «все» (безопасная, быстрая, редкая, легкая и т.д.)

Это то, что действительно следует обратить внимание, если много информация должна быть передана через узлы. Механизм сериализации может быть изменен для отправки половины данных. Существует много раз, когда узкие места не находятся на платформе, но в количестве, которое отправляется через провод, могут сэкономить вам тысячи DLL на аппаратных средствах.

Вот статья. http://java.sun.com/developer/technicalArticles/Programming/serialization/

+0

Это также полезно для пользовательской сериализации для объектов с несериализуемыми элементами. – Jorn 2008-11-02 21:36:21

20

Вы можете объявить класс в методе:

public Foo foo(String in) { 
    class FooFormat extends Format { 
     public Object parse(String s, ParsePosition pp) { // parse stuff } 
    } 
    return (Foo) new FooFormat().parse(in); 

} 
+0

Вы могли бы также просто перейти в новый формат() {, вместо объявления класса FooFormat – Pyrolistical 2008-10-03 19:23:54

+4

Анонимные классы переоценены. Попробуйте отлаживать один раз или поддерживать его в поле, и вы увидите, что я имею в виду. Как только вы потеряете номера строк в сборке релизов, они очень * трудно отслеживать. – TREE 2008-11-10 14:36:25

8

аннотаций Processing API из Java 6 выглядит очень перспективным для генерации кода и статической верификации кода.

82

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

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

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; 
} 
+0

Это удивительно. Можно ли сказать: «Значение конечной переменной можно установить один раз», независимо от того, где происходит набор? – 2009-02-04 19:12:34

+29

Да, но более сильно: «Значение конечной переменной должно быть установлено один раз» – 2009-02-04 22:15:26

3

Несколько лет назад, когда я должен был сделать Java (1.4.x) Я хотел метод Eval() и Солнца Javac есть (был ?), написанный на Java, поэтому нужно было просто связать tools.jar и использовать его с помощью некоторого клея-кода.

23

Обработка Java делает аккуратный трюк в определении переменной, если вы не используете инициализатор по умолчанию.

Это даст вам ошибку во время компиляции, когда у вас есть путь, где X не определен правильно. Это помогло мне несколько раз, и я принял к рассмотрению инициализации по умолчанию, как это:

 
int x=0; 
String s=null; 

быть плохой шаблон поскольку он блокирует эту информацию полезной проверки.

Сказанное, иногда трудно обойтись - мне пришлось вернуться и редактировать в нуле, когда это имело смысл по умолчанию, но я больше не ставил его на первый проход.

7

Вы можете получить доступ к конечным локальным переменным и параметрам в блоках инициализации и методах локальных классов. Рассмотрим это:

final String foo = "42"; 
    new Thread() { 
     public void run() { 
      dowhatever(foo); 
     } 
    }.start(); 

Немного похоже на закрытие, не так ли?

+0

Конечно, потому что вы не можете получить доступ к нефиналам. – 2008-12-16 06:57:26

+0

Я знал, что вы не можете участвовать в нефинале, но я был удивлен, что вы * можете * получить финал. – 2008-12-17 17:47:37

27

Значение:

new URL("http://www.yahoo.com").equals(new URL("http://209.191.93.52")) 

является true.

(от Java Puzzlers)

+48

Только если вы подключены к Интернету. Если он не может разрешить адрес, он вернет false, и поэтому класс URL нарушает соглашение equals(). Лучше использовать класс URI в java.net. – Jorn 2008-11-02 21:39:54

89

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

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"); 
         } 
        }); 
       }}); 
     }}); 
    }}; 
+0

Как-то, это немного похоже на то, что в Java добавлено ключевое слово (с функциональностью, фактически). Может быть очень удобно, недавно я хрюкнул, потому что init массивов не было доступно для Коллекций. Благодаря! – PhiLho 2008-12-13 09:06:07

+15

Существует один побочный эффект от использования этого. Создаются анонимные объекты, что может быть не всегда хорошо. – amit 2009-02-10 08:14:56

104

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

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

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

+23

Важная вещь в этом - при вызове метода вы можете написать: foo («first», «second», третий ") – 2009-03-25 20:03:14

15

Javadoc - при написании правильно (не всегда в случае с некоторыми разработчиками, к сожалению), он дает четкое, последовательное описание того, что должен делать код, в отличие от того, что он на самом деле делает. Затем его можно превратить в удобный для просмотра набор документации HTML. Если вы используете непрерывную интеграцию и т. Д., Она может генерироваться регулярно, чтобы все разработчики могли видеть последние обновления.

+12

и красота, с которой она всплывает в Eclipse, когда вы наводите курсор на метод ... – Nivas 2009-01-27 21:08:13

4

SwingWorker для удобства управления обратными вызовами пользовательского интерфейса из фоновых потоков.

6

экземпляры одного класса могут получить доступ к закрытым членам других случаях:

class Thing { 
    private int x; 

    public int addThings(Thing t2) { 
    return this.x + t2.x; // Can access t2's private value! 
    } 
} 
+2

, что одновременно удивительно и страшно .. – Chii 2009-01-07 15:12:33

+1

Почему это удивительно? – 2009-01-07 18:27:16

+0

Только до недавнего времени я узнал об этом, и кто-то должен был указать на него в комментарии в моем блоге. – moffdub 2009-01-08 00:29:49

4

Видимо с некоторыми отладочных версий есть вариант, который сбрасывает родной (JIT) код сборки из HotSpot: http://weblogs.java.net/blog/kohsuke/archive/2008/03/deep_dive_into.html

К сожалению, я не смог найти сборку по ссылке в этом сообщении, если кто-то может найти более точный URL-адрес, я бы с удовольствием поиграл с ним.

+2

http://download.java.net/jdk6/binaries, а затем для любой платформы вы используете последнюю ссылку (с отладкой в ​​имени). Я люблю эту функцию! – akuhn 2009-04-17 01:05:32

38

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

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

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

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

14

strictfp ключевых слов. (Я никогда не видел, чтобы он использовался в реальном приложении, хотя :)

Вы можете получить класс для примитивных типов, используя следующие обозначения: int.class, float.class и т. Д. Очень полезно при отражении.

Окончательные массивы могут быть использованы для значений «возврата» от анонимных внутренних классов (предупреждение, бесполезный пример ниже):

final boolean[] result = new boolean[1]; 
SwingUtilities.invokeAndWait(new Runnable() { 
    public void run() { result[0] = true; } 
}); 
+0

, используя последний массив, чтобы вернуться из внутреннего класса анонов, как это, вероятно, не рекомендуется хорошая практика программирования ... – Chii 2009-01-07 15:07:29

+0

Romain Guy?Как, Ромайн Гай? ... В любом случае +1 для int.class. Я думал, что Integer.TYPE - единственный способ. – 2009-01-07 18:29:07

142

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

Вместо:

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

просто использовать:

if(aObject instanceof String) 
{ 
    ... 
} 
1

Я наслаждался

  1. javadoc «s taglet и доклет, которые позволяют настраивать вывод JavaDoc.
  2. JDK tools: jstat, jstack и т.д.
5

следующего поколения Java плагин найти в Java 1.6 Update 10, а затем имеет некоторые очень аккуратные черты:

  • Pass java_arguments параметр передавать аргументы Созданная JVM. Это позволяет вам контролировать объем памяти, предоставляемый апплетам.
  • Создайте отдельные загрузчики классов или даже отдельные JVM для каждого апплета.
  • Укажите версию JVM для использования.
  • Установите частичные ядра Java в случаях, когда вам требуется только часть функциональных возможностей библиотеки Java.
  • Улучшенная поддержка Vista.
  • Поддержка (экспериментальная), чтобы вытащить апплет из браузера и продолжать работать, когда вы перемещаетесь.

многие другие вещи, которые задокументированы здесь: http://jdk6.dev.java.net/plugin2/

Больше из этого выпуска здесь: http://jdk6.dev.java.net/6u10ea.html

7

Вы можете построить Sprintf стиль строки, используя string.Format().

String w = "world"; 
String s = String.format("Hello %s %d", w, 3); 

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

Подробнее здесь: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html#syntax

15

со статическим импортом вы можете сделать такие вещи, как:

List<String> myList = list("foo", "bar"); 
Set<String> mySet = set("foo", "bar"); 
Map<String, String> myMap = map(v("foo", "2"), v("bar", "3")); 
+4

вы могли бы даже сделать это с помощью дженериков. У Google Collections есть хорошие утилиты для этого. – 2009-03-27 09:39:10

16

Мне нравится статический импорт методов.

Например создайте следующий класс Util:

package package.name; 

public class util { 

    private static void doStuff1(){ 
     //the end 
    } 

    private static String doStuff2(){ 
     return "the end"; 
    } 

} 

Затем использовать его как это.

import static package.name.util.*; 

public class main{ 

    public static void main(String[] args){ 
      doStuff1(); // wee no more typing util.doStuff1() 
      System.out.print(doStuff2()); // or util.doStuff2() 
    } 

} 

Static Imports работает с любым классом, даже Math ...

import static java.lang.Math.*; 
import static java.lang.System.out; 
public class HelloWorld { 
    public static void main(String[] args) { 
     out.println("Hello World!"); 
     out.println("Considering a circle with a diameter of 5 cm, it has:"); 
     out.println("A circumference of " + (PI * 5) + "cm"); 
     out.println("And an area of " + (PI * pow(5,2)) + "sq. cm"); 
    } 
} 
16

List.subList возвращает представление в первоначальном списке

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

Список Подсписок (интермедиат fromIndex, внутр toIndex)

«Этот метод устраняет необходимость в операции явного диапазона (подобного, которые обычно существуют для массивов). Любая операция, которая ожидает список может быть используется в качестве операции диапазона, передавая вид подсписок вместо целого списка Например, следующая идиома удаляет диапазон элементов из списка:.

 list.subList(from, to).clear(); 

Подобные идиомы могут быть построены для IndexOf и LastIndexOf, и все алгоритмов в классе Collections можно применить к сублисту. "

34

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

112

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

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

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

5

Типы перекрестков позволяют вам (kinda sorta) делать перечисления, имеющие иерархию наследования. Вы не можете наследовать реализацию, но можете делегировать ее классу-помощнику.

enum Foo1 implements Bar {} 
enum Foo2 implements Bar {} 

class HelperClass { 
    static <T extends Enum<T> & Bar> void fooBar(T the enum) {} 
} 

Это полезно, когда у вас есть несколько разных перечислений, которые реализуют какой-то узор.Например, несколько пар перечислений, которые имеют отношения родитель-потомок.

enum PrimaryColor {Red, Green, Blue;} 
enum PastelColor {Pink, HotPink, Rockmelon, SkyBlue, BabyBlue;} 

enum TransportMedium {Land, Sea, Air;} 
enum Vehicle {Car, Truck, BigBoat, LittleBoat, JetFighter, HotAirBaloon;} 

Вы можете написать общие методы, которые говорят, «Хорошо, учитывая значение перечисления того родитель некоторых других значений перечислений, какой процент от всех возможных детей перечислений типа ребенка имеет конкретное родительское значение в качестве своего родителя ? ", и все это будет набирать и делать без кастинга. (например, что «Море» составляет 33% от всех возможных транспортных средств, а «Зеленый» - 20% от всех возможных пастелей).

Код выглядит следующим образом. Это довольно противно, но есть способы сделать это лучше. Обратите внимание, в частности, что сами классы «листа» довольно опрятные - у общих классов есть декларации, которые ужасно уродливы, но вы только пишете их один. Как только общие классы существуют, их легко использовать.

import java.util.EnumSet; 

import javax.swing.JComponent; 

public class zz extends JComponent { 

    public static void main(String[] args) { 
     System.out.println(PrimaryColor.Green + " " + ParentUtil.pctOf(PrimaryColor.Green) + "%"); 
     System.out.println(TransportMedium.Air + " " + ParentUtil.pctOf(TransportMedium.Air) + "%"); 
    } 


} 

class ParentUtil { 
    private ParentUtil(){} 
    static <P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> // 
    float pctOf(P parent) { 
     return (float) parent.getChildren().size()/// 
       (float) EnumSet.allOf(parent.getChildClass()).size() // 
       * 100f; 
    } 
    public static <P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> // 
    EnumSet<C> loadChildrenOf(P p) { 
     EnumSet<C> cc = EnumSet.noneOf(p.getChildClass()); 
     for(C c: EnumSet.allOf(p.getChildClass())) { 
      if(c.getParent() == p) { 
       cc.add(c); 
      } 
     } 
     return cc; 
    } 
} 

interface Parent<P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> { 
    Class<C> getChildClass(); 

    EnumSet<C> getChildren(); 
} 

interface Child<P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> { 
    Class<P> getParentClass(); 

    P getParent(); 
} 

enum PrimaryColor implements Parent<PrimaryColor, PastelColor> { 
    Red, Green, Blue; 

    private EnumSet<PastelColor> children; 

    public Class<PastelColor> getChildClass() { 
     return PastelColor.class; 
    } 

    public EnumSet<PastelColor> getChildren() { 
     if(children == null) children=ParentUtil.loadChildrenOf(this); 
     return children; 
    } 
} 

enum PastelColor implements Child<PrimaryColor, PastelColor> { 
    Pink(PrimaryColor.Red), HotPink(PrimaryColor.Red), // 
    Rockmelon(PrimaryColor.Green), // 
    SkyBlue(PrimaryColor.Blue), BabyBlue(PrimaryColor.Blue); 

    final PrimaryColor parent; 

    private PastelColor(PrimaryColor parent) { 
     this.parent = parent; 
    } 

    public Class<PrimaryColor> getParentClass() { 
     return PrimaryColor.class; 
    } 

    public PrimaryColor getParent() { 
     return parent; 
    } 
} 

enum TransportMedium implements Parent<TransportMedium, Vehicle> { 
    Land, Sea, Air; 

    private EnumSet<Vehicle> children; 

    public Class<Vehicle> getChildClass() { 
     return Vehicle.class; 
    } 

    public EnumSet<Vehicle> getChildren() { 
     if(children == null) children=ParentUtil.loadChildrenOf(this); 
     return children; 
    } 
} 

enum Vehicle implements Child<TransportMedium, Vehicle> { 
    Car(TransportMedium.Land), Truck(TransportMedium.Land), // 
    BigBoat(TransportMedium.Sea), LittleBoat(TransportMedium.Sea), // 
    JetFighter(TransportMedium.Air), HotAirBaloon(TransportMedium.Air); 

    private final TransportMedium parent; 

    private Vehicle(TransportMedium parent) { 
     this.parent = parent; 
    } 

    public Class<TransportMedium> getParentClass() { 
     return TransportMedium.class; 
    } 

    public TransportMedium getParent() { 
     return parent; 
    } 
} 
5

Читайте «Яблочные головоломки» Джошуа Блоха, и вы будете просветлены и в ужасе.

6

Исходный код URL. Например. вот некоторые легальный источник Java-код:

http://google.com 

(Да, это было в Java Puzzlers я смеялся ....)

8

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

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

public class Foo { 
    private int bar; 

    public Foo() { 
     setBar(17); 
    } 

    private void setBar(int bar) { 
     this.bar=bar; 
    } 

    public int getBar() { 
     return bar; 
    } 

    public String toString() { 
     return "Foo[bar="+bar+"]"; 
    } 
} 

Выполнение программы ...

import java.lang.reflect.*; 

public class AccessibleExample { 
    public static void main(String[] args) 
     throws NoSuchMethodException,IllegalAccessException, InvocationTargetException, NoSuchFieldException { 
     Foo foo=new Foo(); 
     System.out.println(foo); 

     Method method=Foo.class.getDeclaredMethod("setBar", int.class); 
     method.setAccessible(true); 
     method.invoke(foo, 42); 

     System.out.println(foo); 
     Field field=Foo.class.getDeclaredField("bar"); 
     field.setAccessible(true); 
     field.set(foo, 23); 
     System.out.println(foo); 
    } 
} 

... даст следующий вывод: функция

Foo[bar=17] 
Foo[bar=42] 
Foo[bar=23] 
12

Часть, часть заморачиваться: String в Java обработки, чтобы сделать его 'появляются' родной тип (использование операторов на них, +, + =)

Будучи в состоянии написать:

String s = "A"; 
s += " String"; // so s == "A String" 

очень удобно, но это просто синтаксический сахар для (т.е. компилируется в):

String s = new String("A"); 
s = new StringBuffer(s).append(" String").toString(); 

ergo Объектная инстанция и 2 метода вызова для простой конкатенации. Представьте себе построить длинную строку внутри цикла таким образом !? И все методы StringBuffer объявляются синхронизированными. К счастью, в (я думаю) Java 5 они ввели StringBuilder, который идентичен StringBuffer без синхронизации.

петля, такие как:

String s = ""; 
for (int i = 0 ; i < 1000 ; ++i) 
    s += " " + i; // Really an Object instantiation & 3 method invocations! 

может (должно) быть переписан в вашем коде, как:

StringBuilder buf = new StringBuilder(); // Empty buffer 
for (int i = 0 ; i < 1000 ; ++i) 
    buf.append(' ').append(i); // Cut out the object instantiation & reduce to 2 method invocations 
String s = buf.toString(); 

и будет работать примерно 80 +% быстрее, чем исходная петля! (до 180% на некоторых тестах, которые я выполнил)

30

Возможно, самой удивительной скрытой функцией является класс sun.misc.Unsafe.

http://www.docjar.com/html/api/ClassLib/Common/sun/misc/Unsafe.java.html

Вы можете;

  • Создать объект без вызова конструктора.
  • Бросьте любое исключение даже Исключение, не беспокоясь о предложениях бросков по методам. (Есть и другие способы сделать это, я знаю)
  • Получить/установить случайно полученные поля в объекте без использования отражения.
  • выделить/бесплатно/скопировать/изменить размер блока памяти, который может быть длинным (64-разрядным) размером.
  • Получите расположение полей в объекте или статических полях в классе.
  • самостоятельно блокирует и блокирует блокировку объекта. (например, синхронизация без блока)
  • определяют класс из предоставленных байт-кодов. Вместо того, чтобы загрузчик классов определял, каков должен быть код байта. (Вы можете сделать это и с отражением)

BTW: Неправильное использование этого класса приведет к уничтожению JVM. Я не знаю, какие JVM поддерживают этот класс, поэтому он не переносится.

58

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

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

Трюк оптимизации, который упрощает работу вашего кода и менее восприимчив к ошибке параллелизма.

public class Slow { 
    /** Loop counter; initialized to 0. */ 
    private long i; 

    public static void main(String args[]) { 
    Slow slow = new Slow(); 

    slow.run(); 
    } 

    private void run() { 
    while(i++ < 10000000000L) 
     ; 
    } 
} 

$ время ява Медленные
реальные 0m15.397s
$ время ява Медленные
реальные 0m20.012s
$ время ява Slow
реальные 0m18.645s

Средний балл: 18.018 с

public class Fast { 
    /** Loop counter; initialized to 0. */ 
    private long i; 

    public static void main(String args[]) { 
    Fast fast = new Fast(); 

    fast.run(); 
    } 

    private void run() { 
    long i = getI(); 

    while(i++ < 10000000000L) 
     ; 

    setI(i); 
    } 

    private long setI(long i) { 
    this.i = i; 
    } 

    private long getI() { 
    return this.i; 
    } 
} 

$ времени ява Быстрые
реальные 0m12.003s
$ времени ява Быстрые
реальные 0m9.840s
$ времени Java Fast
реальные 0m9.686s

Средний балл: 10.509s

Он требует больше байт-кодов для ссылки на переменную класса-класса, чем переменная метода-области. Добавление вызова метода до критического цикла добавляет небольшие накладные расходы (и вызов может быть встроен компилятором в любом случае).

Еще одно преимущество этой техники (всегда использование аксессуаров) заключается в том, что она устраняет потенциальную ошибку в Низкий класс.Если второй поток должен постоянно переустанавливать значение i на 0 (например, по телефону slow.setI(0)), класс Slow никогда не сможет завершить свой цикл. Вызов аксессора и использование локальной переменной устраняет эту возможность.

Протестировано с использованием J2SE 1.6.0_13 на Linux 2.6.27-14.

0

Методы аксессуаров Java Bean do не должны начинаться с «get» и «set».

Даже Джош Блох ошибается в Эффективной Java.

11

Я просто (ре) узнал сегодня, что $ является юридическим именем метода или переменной в Java. В сочетании со статическим импортом может сделать какой-то немного более читаемый код, в зависимости от вашего зрения читаемого:

http://garbagecollected.org/2008/04/06/dollarmaps/

5

Он уже был mentioned, что окончательный массив может быть использован для передачи переменного из анонимнога внутренние классы.

Другим, возможно лучшим и менее уродливым подходом, является использование класса AtomicReference (или AtomicBoolean/AtomicInteger/...) из пакета java.util.concurrent.atomic.

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


Другой полезный родственный картина:

final AtomicBoolean dataMsgReceived = new AtomicBoolean(false); 
final AtomicReference<Message> message = new AtomicReference<Message>(); 
withMessageHandler(new MessageHandler() { 
    public void handleMessage(Message msg) { 
     if (msg.isData()) { 
      synchronized (dataMsgReceived) { 
       message.set(msg); 
       dataMsgReceived.set(true); 
       dataMsgReceived.notifyAll(); 
      } 
     } 
    } 
}, new Interruptible() { 
    public void run() throws InterruptedException { 
     synchronized (dataMsgReceived) { 
      while (!dataMsgReceived.get()) { 
       dataMsgReceived.wait(); 
      } 
     } 
    } 
}); 

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

waitMessageHandler(…) выше еще один полезный шаблон: она устанавливает обработчик где-то, а затем приступает к выполнению прерываемой который может выбросить исключение, а затем удаляет обработчик в конце концов блок, например, так:

private final AtomicReference<MessageHandler> messageHandler = new AtomicReference<MessageHandler>(); 
public void withMessageHandler(MessageHandler handler, Interruptible logic) throws InterruptedException { 
    synchronized (messageHandler) { 
     try { 
      messageHandler.set(handler); 
      logic.run(); 
     } finally { 
      messageHandler.set(null); 
     } 
    } 
} 

Здесь я предполагаю, что сообщение messageHandler (если это не пусто) handleMessage(…) метод вызывается другим потоком при получении сообщения. messageHandler не должен быть просто MessageHandler Тип: таким образом вы будете синхронизировать меняющуюся переменную, что явно является ошибкой.

Конечно, не нужно быть InterruptedException, это может быть что-то вроде IOException, или что-то имеет смысл в определенной части кода.

5

Зам. & массив.Это является законным синтаксис: Строка с [] = {
"123",
"234" ,
};

8

Большинство людей не знают, что они могут клонировать массив.

int[] arr = {1, 2, 3}; 
int[] arr2 = arr.clone(); 
10

Использование StringBuilder вместо StringBuffer, когда вам не нужно синхронизированного управления, включенные в StringBuilder. Это повысит производительность вашего приложения.

Улучшения для Java 7 будет даже лучше, чем любые скрытые возможности Java:

  • Алмазный синтаксис:Link

Не использовать эти бесконечные <> синтаксис при создании экземпляра:

Map<String, List<String>> anagrams = new HashMap<String, List<String>>(); 

// Can now be replaced with this: 

Map<String, List<String>> anagrams = new HashMap<>(); 
  • Строки в коммутаторе:Link

Используйте String переключатель, вместо старого C междунар:

String s = "something"; 
switch(s) { 
case "quux": 
    processQuux(s); 
    // fall-through 

    case "foo": 
    case "bar": 
    processFooOrBar(s); 
    break; 

    case "baz": 
    processBaz(s); 
    // fall-through 

    default: 
    processDefault(s); 
    break; 
} 
  • Автоматическое управление ресурсамиLink

Этот старый код :

static void copy(String src, String dest) throws IOException { 
    InputStream in = new FileInputStream(src); 
    try { 
     OutputStream out = new FileOutputStream(dest); 
     try { 
      byte[] buf = new byte[8 * 1024]; 
      int n; 
      while ((n = in.read(buf)) >= 0) 
       out.write(buf, 0, n); 
     } finally { 
      out.close(); 
     } 
    } finally { 
     in.close(); 
    } 
} 

теперь может быть заменен этим гораздо более простым кодом:

static void copy(String src, String dest) throws IOException { 
    try (InputStream in = new FileInputStream(src); 
      OutputStream out = new FileOutputStream(dest)) { 
     byte[] buf = new byte[8192]; 
     int n; 
     while ((n = in.read(buf)) >= 0) 
      out.write(buf, 0, n); 
    } 
} 
4

Вы можете включить (это) внутри определений методов классов перечислений. Сделал меня кричать «whut!» громко, когда я обнаружил, что это действительно работает.

7

На самом деле, что мне нравится в Java, так это несколько скрытых трюков. Это очень очевидный язык. Настолько, что через 15 лет почти каждый, о котором я могу думать, уже указан на этих нескольких страницах.

Возможно, большинство людей знает, что Collections.synchronizedList() добавляет синхронизацию в список. То, что вы не можете знать, если вы не прочитали документацию, состоит в том, что вы можете безопасно перебирать элементы этого списка, синхронизируя сам объект списка.

CopyOnWriteArrayList может быть неизвестен некоторым, а Future представляет интересный способ абстрактного многопоточного доступа к результатам.

Вы можете подключиться к виртуальным машинам (локальным или удаленным), получить информацию о деятельности GC, использовании памяти, дескрипторах файлов и даже размерах объектов через различные API-интерфейсы управления, агента и приложения.

Хотя TimeUnit, возможно, лучше, чем длинный, я предпочитаю класс продолжительности Wicket.

16

О, я почти забыл эту маленькую жемчужину. Попробуйте это на любом запущенном процессе Java:

jmap -histo: жить PID

Вы получите гистограмму объектов живой кучи в данной виртуальной машине. Бесценный, как быстрый способ определить некоторые виды утечек памяти. Другой метод, который я использую для их предотвращения, - это создание и использование ограниченных по размеру подклассов всех классов коллекций. Это приводит к быстрым сбоям в коллекциях вне контроля, которые легко идентифицировать.

16

Функция, с помощью которой вы можете отображать заставки для ваших приложений на основе Java-консоли.

Используйте инструмент командной строки java или javaw с опцией -splash

например:

java -splash:C:\myfolder\myimage.png -classpath myjarfile.jar com.my.package.MyClass 

содержание C:\myfolder\myimage.png будет отображаться в центре экрана, когда вы выполняете класс «ком .my.package.MyClass "

42

При работе в Swing Мне нравится скрытый Ctrl - Shi футы - F1 особенность.

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

-8

Удивляет меня, что интерфейс может расширять несколько интерфейсов, но класс может распространять только один класс.

28

Shutdown Hooks. Это позволяет регистрировать поток, который будет создан немедленно, но начал только тогда, когда JVM заканчивается! Так что это какой-то «глобальный финализатор jvm», и вы можете создавать полезные материалы в этом потоке (например, закрывать java-ресурсы, такие как встроенный сервер hsqldb). Это работает с System.exit() или с CTRL-C/kill -15 (но не с kill -9 в unix, конечно).

Кроме того, это довольно легко настроить.

  Runtime.getRuntime().addShutdownHook(new Thread() { 
        public void run() { 
         endApp(); 
        } 
      });; 
9

Идентификаторы могут содержать символы иностранного языка как умляутов:

вместо написания:

String title=""; 

кто-то может написать:

String Überschrift=""; 
6

Не читал об этом

Integer a = 1; 
Integer b = 1; 
Integer c = new Integer(1); 
Integer d = new Integer(1); 

Integer e = 128; 
Integer f = 128; 

assertTrue (a == b); // again: this is true! 
assertFalse(e == f); // again: this is false! 
assertFalse(c == d); // again: this is false! 

подробнее об этом с помощью функции поиска пул Явы целого числа (внутренний 'кэш' от -128 до 127 для Autoboxing) или посмотреть в Integer. valueOf

2

Вы можете переопределить метод и есть конструктор суперкласса назвать его (это может стать неожиданностью для программистов C++.)

Example

29

Это мой список.

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

import java.rmi.RemoteException; 

class Thrower { 
    public static void spit(final Throwable exception) { 
     class EvilThrower<T extends Throwable> { 
      @SuppressWarnings("unchecked") 
      private void sneakyThrow(Throwable exception) throws T { 
       throw (T) exception; 
      } 
     } 
     new EvilThrower<RuntimeException>().sneakyThrow(exception); 
    } 
} 

public class ThrowerSample { 
    public static void main(String[] args) { 
     Thrower.spit(new RemoteException("go unchecked!")); 
    } 
} 

Также вы можете, как знать, что вы можете бросить 'нуль' ...

public static void main(String[] args) { 
    throw null; 
} 

Угадайте, что это печатает:

Long value = new Long(0); 
System.out.println(value.equals(0)); 

И, г uess, что это возвращает:

public int returnSomething() { 
    try { 
     throw new RuntimeException("foo!"); 
    } finally { 
     return 0; 
    } 
} 

выше не должно удивлять хороших разработчиков.


В Java вы можете объявить массив в следующих допустимых способах:

String[] strings = new String[] { "foo", "bar" }; 
// the above is equivalent to the following: 
String[] strings = { "foo", "bar" }; 

Так следующий Java кода вполне допустим:

public class Foo { 
    public void doSomething(String[] arg) {} 

    public void example() { 
     String[] strings = { "foo", "bar" }; 
     doSomething(strings); 
    } 
} 

Есть ли действительная причина, почему, вместо того, следующий код не должен быть действительным?

public class Foo { 

    public void doSomething(String[] arg) {} 

    public void example() { 
     doSomething({ "foo", "bar" }); 
    } 
} 

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

40

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

(Explanation)

4

Вы можете добавить во время выполнения проверки родовых типов с использованием Class<T> объекта, это очень удобно, когда класс создается в файле конфигурации где-то и нет никакого способа, чтобы добавить проверку времени компиляции для родового типа класса. Вы не хотите, чтобы класс взорвался во время выполнения, если приложение было настроено неправильно, и вы не хотите, чтобы все классы были пронизаны экземпляром проверок.

public interface SomeInterface { 
    void doSomething(Object o); 
} 
public abstract class RuntimeCheckingTemplate<T> { 
    private Class<T> clazz; 
    protected RuntimeChecking(Class<T> clazz) { 
    this.clazz = clazz; 
    } 

    public void doSomething(Object o) { 
    if (clazz.isInstance(o)) { 
     doSomethingWithGeneric(clazz.cast(o)); 
    } else { 
     // log it, do something by default, throw an exception, etc. 
    } 
    } 

    protected abstract void doSomethingWithGeneric(T t); 
} 

public class ClassThatWorksWithStrings extends RuntimeCheckingTemplate<String> { 
    public ClassThatWorksWithStrings() { 
    super(String.class); 
    } 

    protected abstract void doSomethingWithGeneric(T t) { 
    // Do something with the generic and know that a runtime exception won't occur 
    // because of a wrong type 
    } 
} 
-3

Я был удивлен, когда я первый заметил троичной-оператор, который приравнивает простой, если-то-иначе заявление:

minVal = (a < b) ? a : b; 
9

Я могу добавить объект сканера. Это лучше всего подходит для синтаксического анализа.

String input = "1 fish 2 fish red fish blue fish"; 
Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*"); 
System.out.println(s.nextInt()); 
System.out.println(s.nextInt()); 
System.out.println(s.next()); 
System.out.println(s.next()); 
s.close(); 
14

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

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

(new Object() { 
    public String someMethod(){ 
     return "some value"; 
    } 
}).someMethod(); 

Вероятно, не очень часто, потому что не очень полезно либо, вы можете вызвать метод его только при определении его (или с помощью отражения)

21

Это на самом деле не скрытая функция, но она дает мне большое удивление, когда я увидел это компилируется нормально:

public int aMethod(){ 
    http://www.google.com 
    return 1; 
} 

причина, по которой он компилируется, заключается в том, что строка http://www.google.com часть «http:» обрабатывается компилятором как метка, а остальная часть строки является комментарием.

Итак, если вы хотите написать некоторый код bizzare (или запутанный код), просто разместите там много адресов. ;-)

13

C-Style Е() :)

System.out.printf("%d %f %.4f", 3,Math.E,Math.E); 

Выход: 3 2,718282 2,7183

Двоичный поиск (и это возвращаемое значение)

int[] q = new int[] { 1,3,4,5}; 
int position = Arrays.binarySearch(q, 2); 

Подобно C#, если «2» не найден в массиве, он возвращает отрицательное значение, но если вы возьмете «Дополнение» 1 от возвращаемого значения, вы фактически получите позицию, в которой «2» можно вставить.

В приведенном выше примере позиция = -2, ~ position = 1, которая является позицией, в которой должно быть вставлено 2 ... она также позволяет находить «ближайший» совпадение в массиве.

Я считаю его довольно изящным ... :)

23

Не так скрыт, но интересно.

Вы можете иметь «Здравствуй, мир» без основного метода (он бросает подумал NoSuchMethodError)

Первоначально Написал RusselW на Strangest language feature

public class WithoutMain { 
    static { 
     System.out.println("Look ma, no main!!"); 
     System.exit(0); 
    } 
} 

$ java WithoutMain 
Look ma, no main!! 
Смежные вопросы