Сведения о вопросе

Математик

06:50, 26th August, 2020

Теги

java    

Скрытые возможности Java

Просмотров: 496   Ответов: 25

После прочтения скрытых функций C# я задался вопросом, каковы некоторые из скрытых функций Java?



  Сведения об ответе

#hash

17:48, 29th August, 2020

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

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

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


  Сведения об ответе

COOL

10:49, 28th August, 2020

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

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

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


  Сведения об ответе

VERSUION

18:54, 24th August, 2020

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

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


  Сведения об ответе

DINO

00:50, 23rd August, 2020

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


  Сведения об ответе

repe

16:36, 9th August, 2020

Classpath диких карт с 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


  Сведения об ответе

прога

09:20, 8th August, 2020

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


  Сведения об ответе

padenie

12:05, 23rd August, 2020

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

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

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

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

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


  Сведения об ответе

ASSembler

09:37, 13th August, 2020

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


  Сведения об ответе

DO__IT

21:09, 21st August, 2020

Никогда не видел, чтобы кто-то упоминал instanceof, реализованный таким образом, что проверка на null не нужна.

Вместо:

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

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

if( aObject instanceof String )
{
    ...
}


  Сведения об ответе

PIRLO

02:00, 15th August, 2020

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

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

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

Вы даже можете иметь "constant specific class body", который позволяет конкретному значению перечисления переопределять методы.

Более подробная документация здесь .


  Сведения об ответе

9090

21:06, 1st October, 2020

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

Collections.<String,Integer>emptyMap()


  Сведения об ответе

ASER

23:14, 21st August, 2020

Вы можете использовать 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

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


  Сведения об ответе

LAST

13:17, 15th August, 2020

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

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

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


  Сведения об ответе

nYU

20:18, 7th August, 2020

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

windows: CTRL - Break в окне java cmd/консоли

unix: kill -3 PID


  Сведения об ответе

прога

09:08, 2nd August, 2020

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

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

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

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

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


  Сведения об ответе

piter

04:41, 22nd August, 2020

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


  Сведения об ответе

lesha

04:02, 17th August, 2020

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

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

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


  Сведения об ответе

#hash

08:59, 8th August, 2020

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

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

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


  Сведения об ответе

screen

16:38, 5th August, 2020

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

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


  Сведения об ответе

+-*/

03:06, 3rd August, 2020

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

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


  Сведения об ответе

crush

04:06, 7th August, 2020

Использование этого ключевого слова для доступа к полям / методам содержащего класса из внутреннего класса. В приведенном ниже, довольно надуманном примере, мы хотим использовать поле 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;
}
}


  Сведения об ответе

SSESION

14:35, 2nd August, 2020

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

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

    System.exit(0);
  }
}

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


  Сведения об ответе

FAriza

22:34, 11th August, 2020

Это не совсем "hidden features" и не очень полезно, но может быть чрезвычайно интересно в некоторых случаях:
Класс 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);
        }
    };
}


  Сведения об ответе

SILA

22:47, 11th August, 2020

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

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


  Сведения об ответе

KOMP

19:33, 23rd August, 2020

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

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться