C#の隠し機能を読んだ後、Javaの隠し機能は何ですか?
C#の隠し機能を読んだ後、Javaの隠し機能は何ですか?
回答:
Double Braceの初期化は、数か月前に初めて発見し、これまで聞いたことがありませんでした。
ThreadLocalsは通常、スレッドごとの状態を保存する方法としてそれほど広く知られていません。
JDK 1.5 Javaはロックだけでなく、非常に適切に実装された堅牢な同時実行ツールを備えているため、java.util.concurrentにあり、特に興味深い例は、比較を実装するスレッドセーフプリミティブを含むjava.util.concurrent.atomicサブパッケージです。-and-swap操作。これらの操作の実際のネイティブハードウェアサポートバージョンにマップできます。
型パラメーターの分散における結合和:
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の両方のメソッドを呼び出すことができることです。
先日、インスタンス初期化子に驚きました。私はいくつかのコード折り畳みメソッドを削除し、複数のインスタンス初期化子を作成してしまいました:
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開発者にインタビューしたほとんどの人にとって、blocksというラベルの付いたポジションは非常に驚くべきものです。次に例を示します。
// 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以降に導入されている共変戻り値型はどうですか?それは魅力的ではない追加なのでかなり宣伝されていませんが、私が理解しているように、ジェネリックが機能するためには絶対に必要です。
基本的に、コンパイラーはサブクラスがオーバーライドされたメソッドの戻り値の型を、元のメソッドの戻り値の型のサブクラスになるように絞り込むことができるようになりました。したがって、これは許可されています:
class Souper {
Collection<String> values() {
...
}
}
class ThreadSafeSortedSub extends Souper {
@Override
ConcurrentSkipListSet<String> values() {
...
}
}
サブクラスのvalues
メソッドを呼び出して、にダウンキャストすることなく sのソートされたスレッドセーフSet
を取得できます。String
ConcurrentSkipListSet
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から
nullのチェックが不要になるような方法でinstanceofが実装されていることに言及している人を見たことはありません。
の代わりに:
if( null != aObject && aObject instanceof String )
{
...
}
ただ使う:
if( aObject instanceof String )
{
...
}
free
ingまたはdelete
ingする前にnullをチェックすることです。そのような基本的な概念。
列挙型でメソッドとコンストラクターを許可すると、驚いた。例えば:
enum Cats {
FELIX(2), SHEEBA(3), RUFUS(7);
private int mAge;
Cats(int age) {
mAge = age;
}
public int getAge() {
return mAge;
}
}
特定の列挙値がメソッドをオーバーライドできるようにする「定数の特定のクラス本体」を持つこともできます。
詳細なドキュメントはこちら。
mAge
最終的なはずです。enumに最終でないフィールドがある理由はめったにありません。
ジェネリックメソッドの型パラメーターは、次のように明示的に指定できます。
Collections.<String,Integer>emptyMap()
public static <T> T foo(T t)
。その後、Class.<Type>foo(t);
return set1.equals(set2) ? new ArrayList<String>(set1) : Collections.<String>emptyList()
。また、単純なCollections.emptyMap()でコンパイルエラーが発生するいくつかのメソッド呼び出しにも役立ちます。
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 {
インターフェイスを使用することにより、開発者は独自の戦略を定義できます。enum
手段を使用して、組み込みのコレクション(5つのコレクション)を定義できます。
Java 1.5以降、Javaには可変アリティの関数を作成するためのより明確な構文があります。したがって、配列を渡すだけでなく、次のことができます
public void foo(String... bars) {
for (String bar: bars)
System.out.println(bar);
}
棒は、指定されたタイプの配列に自動的に変換されます。大きな勝利ではありませんが、それでも勝利です。
私のお気に入り:すべてのスレッドスタックトレースを標準出力にダンプします。
窓:CTRL- BreakあなたのjavaのCMD /コンソールウィンドウで
UNIX: kill -3 PID
Break
キーがあることを教えてくれました。
いくつかの人々がインスタンス初期化子について投稿しました、ここにそれの良い使い方があります:
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");
}
});
}});
}});
}};
最終的な初期化は延期できます。
ロジックの複雑なフローでも戻り値が常に設定されるようにします。ケースを見逃して、誤って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;
}
Javaのもう1つの「見過ごされている」機能は、JVM自体だと思います。それはおそらく利用可能な最高のVMです。そして、それは多くの興味深く有用な言語(Jython、JRuby、Scala、Groovy)をサポートします。これらの言語はすべて、簡単かつシームレスに連携できます。
(scalaの場合のように)新しい言語を設計する場合、既存のすべてのライブラリーをすぐに使用できるため、言語は最初から「有用」です。
これらの言語はすべて、HotSpotの最適化を利用しています。VMは非常によく監視され、デバッグ可能です。
匿名のサブクラスを定義して、インターフェースを実装していなくても、直接そのメソッドを呼び出すことができます。
new Object() {
void foo(String s) {
System.out.println(s);
}
}.foo("Hello");
start()
)で呼び出されるメソッドは、実際にはサブクラスで定義されていません...
のasListメソッドでjava.util.Arrays
は、可変引数、ジェネリックメソッド、オートボクシングをうまく組み合わせることができます。
List<Integer> ints = Arrays.asList(1,2,3);
Arrays.asList
は、set()
要素にはできるがadd()
やにはない、珍しい機能がありますremove()
。だから私は、通常でラップnew ArrayList(...)
たりしてCollections.unmodifiableList(...)
、私は、リストの修正をしたいかどうかに応じて、。
このキーワードを使用して、内部クラスから包含クラスのフィールド/メソッドにアクセスします。以下では、かなり不自然な例で、匿名の内部クラスのコンテナークラスの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;
}
}
MyActivity.this
ます。
実際には機能ではありませんが、いくつかのWebページで最近発見した面白いトリックです。
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で直接メモリ管理を実装できるようになりますこれをたくさん試してみると):
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機能。
現在のウィンドウのコンポーネントツリーをダンプします。
(そのキーストロークを他の何かにバインドしていないと仮定します。)
私の投票は、並行コレクションと柔軟なエグゼキューターがjava.util.concurrentに行き、とりわけスレッドプール、スケジュールされたタスク、調整されたタスクを許可します。DelayQueueは私の個人的なお気に入りであり、指定された遅延後に要素が使用可能になります。
java.util.TimerとTimerTaskは安全に休止できます。
また、完全に隠されているわけではありませんが、日付と時刻に関連する他のクラスとは異なるパッケージにあります。java.util.concurrent.TimeUnitは、ナノ秒、マイクロ秒、ミリ秒、秒の間で変換するときに役立ちます。
通常のsomeValue * 1000またはsomeValue / 1000よりもはるかによく読み取れます。
CountDownLatch
とCyclicBarrier
- そう便利!
言語レベルのassertキーワード。
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;
}
i
ほとんどの人が配列要素ではなくインデックスであることを期待するので、ここでの使用は非常に混乱すると思います。
私は個人的java.lang.Void
に非常に遅くに発見しました-ジェネリックと組み合わせてコードの可読性を向上させます。Callable<Void>