面白い - javaで作られたゲーム




Javaの隠された機能 (20)

C#の隠された機能を 読んだ後、私は思った、Javaの隠された機能のいくつかは何ですか?


私は個人的には java.lang.Void 非常に遅く 発見しました - ジェネリックと組み合わせてコードの読みやすさを改善します。 Callable<Void>


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の資料へのリンク


JDK 1.5から導入されてきた 共変戻り型は どうですか。 それはセクシーでない追加であるので、それはかなり貧弱に公表されていません、しかし私がそれを理解するように、ジェネリックが働くために絶対に必要です。

基本的に、コンパイラはサブクラスが、オーバーライドされたメソッドの戻り型を元のメソッドの戻り型のサブクラスに絞り込むことを可能にしました。 だからこれは許可されています:

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

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

サブクラスの values メソッドを呼び出して、 ConcurrentSkipListSet にダウンキャスト する ことなく 、ソートされたスレッドセーフな StringSet を取得できます。


JDK 1.6_07 +にはVisualVM(bin / jvisualvm.exe)というアプリが含まれています。これは多くのツールの上にある素晴らしいGUIです。 JConsoleよりも包括的です。



Swingで作業しているとき、私は隠された Ctrl - Shift - F1 機能が好きです。

現在のウィンドウのコンポーネントツリーをダンプします。
(あなたがそのキーストロークを他の何かに束縛していないと仮定します。)


nullをチェックする必要がないような方法でinstanceofが実装されていると誰かが言及したことはありません。

の代わりに:

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

ただ使用する:

if( aObject instanceof String )
{
    ...
}

あなたはインターフェースを実装するためにenumを使うことができます。

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 を使用することは、私が1つで構築された(5つの)コレクションを定義できることを意味します。


すべてのクラスファイルは、有効なJVMバイトコードとして識別するために、16進値 0xCAFEBABEで 始まります。

Explanation


ブロックというラベルの付いた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;
            }
        }
    }
}

Javaの goto は単なるキーワードだと誰が言ったのですか :)


先日インスタンス初期化子に驚きました。 私はいくつかのコード折り畳み式メソッドを削除し、複数のインスタンス初期化子を作成することになった。

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

列挙型でメソッドやコンストラクタを許可することは私を驚かせました。 例えば:

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

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

特定のenum値がメソッドをオーバーライドすることを可能にする「定数特定クラス本体」さえ持つことができます。

こちらのドキュメント


型パラメータ分散におけるジョイントユニオン

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

この工夫されたメソッドは、2つの指定されたコレクションが等しい場合、またはそれらのいずれかに指定の要素が含まれている場合はtrueを返し、それ以外の場合はfalseを返します。 注意すべき点は、引数b1とb2に対してComparableとCollectionの両方のメソッドを呼び出すことができるということです。


実際にはJava言語の一部ではありませんが、SunのJDKに付属のjavap逆アセンブラはあまり知られていないか使用されていません。


私のお気に入りは、すべてのスレッドスタックトレースを標準出力にダンプすることです。

windows: CTRL - java cmd / consoleウィンドウを改行する

unix: kill -3 PID


私の投票は java.util.concurrent への同時収集と他のスレッドプール、スケジュールされたタスク、そして調整されたタスクを可能にする柔軟なエグゼキュータです。 DelayQueueは私の個人的なお気に入りで、指定された遅延の後に要素が利用可能になります。

java.util.TimerとTimerTaskは安全に休止できます。

また、正確には隠されていませんが、日付と時刻に関連する他のクラスとは異なるパッケージに入っています。 java.util.concurrent.TimeUnitは、ナノ秒、マイクロ秒、ミリ秒、および秒の間の変換に役立ちます。

通常のsomeValue * 1000やsomeValue / 1000よりもはるかに優れています。


言語レベルの assert キーワード


動的プロキシ (1.3で追加)を使用すると、実行時にインタフェースに準拠した新しい型を定義できます。 それは驚くほど何度も役に立ちます。


java.util.Arrays asList メソッドを使用すると、可変引数、汎用メソッド、およびオートボクシングをうまく組み合わせることができます。

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






java