development

자바의 숨겨진 기능

big-blog 2020. 3. 16. 08:25
반응형

자바의 숨겨진 기능


C #의 숨겨진 기능을 읽은 후 Java의 숨겨진 기능은 무엇입니까?


Double Brace Initialization 은 몇 달 전에 처음 발견했을 때 놀랐습니다.

ThreadLocals 는 일반적으로 스레드 별 상태를 저장하는 방법으로 널리 알려져 있지 않습니다.

JDK 1.5 Java는 잠금을 뛰어 넘어 매우 잘 구현되고 강력한 동시성 도구를 가지고 있기 때문에 java.util.concurrent에 있으며 특히 흥미로운 예제는 비교 를 구현하는 스레드 안전 기본 요소를 포함 하는 java.util.concurrent.atomic 서브 패키지입니다. 스왑 작업을 수행하고 이러한 작업의 실제 기본 하드웨어 지원 버전에 매핑 할 수 있습니다.


유형 모수 분산의 합집합 :

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

예를 들어 Comparable과 Collection 모두의 매개 변수를 사용하려는 경우 :

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에 대해 Comparable 및 Collection의 메소드를 호출 할 수 있다는 것입니다.


다른 날 인스턴스 초기화 프로그램에 놀랐습니다. 코드 접힌 메소드를 삭제하고 여러 인스턴스 이니셜 라이저를 만들었습니다.

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

JDK 1.6_07 +에는 VisualVM (bin / jvisualvm.exe)이라는 앱이 포함되어 있습니다.이 도구는 여러 도구 위에있는 멋진 GUI입니다. 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자바에서 키워드라고 했습니까? :)


방법에 대한 공변 반환 형식 JDK 1.5부터 장소에왔다? 그것은 섹시하지 않은 추가이기 때문에 꽤 잘 알려지지 않았지만, 그것을 이해함에 따라 제네릭이 작동하려면 절대적으로 필요합니다.

본질적으로, 컴파일러는 이제 서브 클래스가 재정의 된 메소드의 리턴 유형을 원래 메소드의 리턴 유형의 서브 클래스로 좁힐 수있게합니다. 따라서 이것은 허용됩니다.

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

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

당신은 서브 클래스의 호출 할 수있는 values방법 및 정렬 된 스레드 안전 확보 SetString의를 다운 캐스트하지 않고도 받는 사람 ConcurrentSkipListSet.


아무도 null 검사가 필요하지 않은 방식으로 구현 된 인스턴스를 언급 한 적이 없습니다.

대신에:

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

그냥 사용하십시오 :

if( aObject instanceof String )
{
    ...
}

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


열거 형의 메소드와 생성자를 허용하면 나를 놀라게했습니다. 예를 들면 다음과 같습니다.

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

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

특정 열거 형 값이 메서드를 재정의 할 수 있도록하는 "일정한 특정 클래스 본문"을 가질 수도 있습니다.

더 많은 문서는 여기에 있습니다 .


제네릭 메서드의 형식 매개 변수는 다음과 같이 명시 적으로 지정할 수 있습니다.

Collections.<String,Integer>emptyMap()

열거 형을 사용하여 인터페이스를 구현할 수 있습니다.

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

편집 : 몇 년 후 ....

이 기능을 여기에 사용합니다

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 개)을 정의 할 수 있습니다.


Java 1.5부터 Java는 이제 가변 arity의 함수를 작성하기 위해 훨씬 더 깔끔한 구문을 갖습니다. 따라서 배열을 전달하는 대신 다음을 수행 할 수 있습니다.

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

막대는 지정된 유형의 배열로 자동 변환됩니다. 큰 승리는 아니지만 그럼에도 불구하고 승리.


내가 가장 좋아하는 것 : 모든 스레드 스택 추적을 표준 출력으로 덤프합니다.

창 : CTRL- Break자바 cmd를 / 콘솔 창에

유닉스 : 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에 추가됨)를 사용하면 런타임에 인터페이스에 맞는 새 유형을 정의 할 수 있습니다. 놀랍도록 여러 번 유용합니다.


최종 초기화는 연기 될 수 있습니다.

복잡한 논리 리턴 값으로도 항상 설정되도록합니다. 사례를 놓치고 실수로 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;
}

자바의 또 다른 "과시 된"기능은 JVM 자체라고 생각합니다. 아마도 가장 좋은 VM 일 것입니다. 또한 재미 있고 유용한 언어 (Jython, JRuby, Scala, Groovy)를 지원합니다. 모든 언어는 쉽고 원활하게 협력 할 수 있습니다.

스칼라 케이스와 같이 새로운 언어를 디자인하면 기존의 모든 라이브러리를 즉시 사용할 수 있으므로 언어는 처음부터 "유용합니다".

이러한 모든 언어는 HotSpot 최적화를 사용합니다. VM은 매우 잘 모니터링되고 디버깅 가능합니다.


인터페이스를 구현하지 않더라도 익명 서브 클래스를 정의하고 직접 메소드를 호출 할 수 있습니다.

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

asList의 의 방법은 java.util.Arrays가변 인자, 일반적인 방법과 오토 박싱의 좋은 조합을 할 수 있습니다 :

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

키워드를 사용 하여 내부 클래스에서 클래스를 포함하는 필드 / 방법에 액세스합니다. 아래에서 다소 고안된 예에서는 익명의 내부 클래스에서 컨테이너 클래스의 sortAscending 필드를 사용하려고합니다. this.sortAscending 대신 ContainerClass.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;
}
}

실제로는 기능이 아니지만 일부 웹 페이지에서 최근에 발견 한 재미있는 트릭입니다.

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

    System.exit(0);
  }
}

유효한 Java 프로그램입니다 (경고를 생성하더라도). 이유를 모르면 Gregory의 답변을 참조하십시오! ;-) 글쎄, 여기에 구문 강조 표시도 힌트를줍니다!


이것은 "숨겨진 기능"이 아니며 유용하지는 않지만 어떤 경우에는 매우 흥미로울 수 있습니다.
Class sun.misc.Unsafe- 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);
        }
    };
}

숨겨진 같은 스윙 I에서 작업 할 때 Ctrl- Shift- F1기능입니다.

현재 창의 구성 요소 트리를 덤프합니다.
(키 입력을 다른 것으로 바인딩하지 않았다고 가정합니다.)


모든 클래스 파일은 16 진 값 0xCAFEBABE시작하여 유효한 JVM 바이트 코드로 식별합니다.

( 설명 )


필자의 투표는 동시 수집 및 유연한 실행 프로그램 으로 java.util.concurrent에 전달 되며 다른 스레드 풀, 예약 된 작업 및 조정 된 작업이 가능합니다. DelayQueue는 내가 개인적으로 좋아하는 것으로 지정된 지연 후에 요소를 사용할 수 있습니다.

java.util.Timer 및 TimerTask를 안전하게 놓을 수 있습니다.

또한 정확히 숨겨져 있지는 않지만 날짜 및 시간과 관련된 다른 클래스와 다른 패키지로 제공됩니다. java.util.concurrent.TimeUnit은 나노초, 마이크로 초, 밀리 초 및 초 사이를 변환 할 때 유용합니다.

일반적인 someValue * 1000 또는 someValue / 1000보다 훨씬 잘 읽습니다.


언어 수준의 어설 션 키워드


실제로 Java 언어의 일부는 아니지만 Sun의 JDK와 함께 제공되는 javap 디스어셈블러는 널리 알려 지거나 사용되지 않습니다.


1.5에 for-each 루프 구성이 추가되었습니다. 나는 <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 구문은 반복자보다는 색인 변수를 숨기는 배열에도 적용 할 수 있습니다. 다음 메소드는 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<Void>

참고 URL : https://stackoverflow.com/questions/15496/hidden-features-of-java

반응형