C # Gizli Özellikleri okuduktan sonra merak ettim, Java gizli özellikleri nelerdir?
C # Gizli Özellikleri okuduktan sonra merak ettim, Java gizli özellikleri nelerdir?
Yanıtlar:
Double Brace Başlatma , birkaç ay önce ilk keşfettiğimde, daha önce hiç duymadığım için beni şaşırttı.
ThreadLocals tipik olarak thread başına durumu depolamanın bir yolu olarak bilinmemektedir.
JDK 1.5 Java, kilitlerin ötesinde son derece iyi uygulanmış ve sağlam eşzamanlılık araçlarına sahip olduğundan, java.util.concurrent'ta yaşarlar ve özellikle ilginç bir örnek, karşılaştırmayı uygulayan iplik açısından güvenli ilkelleri içeren java.util.concurrent.atomic alt paketidir. -ve-takas işlemi ve bu işlemlerin yerel donanım destekli gerçek sürümleriyle eşleştirilebilir.
Tür parametre varyansında ortak birleşim:
public class Baz<T extends Foo & Bar> {}
Örneğin, hem Karşılaştırılabilir hem de Koleksiyon olan bir parametre almak istiyorsanız:
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);
}
Verilen bu iki koleksiyon eşitse veya bunlardan herhangi biri verilen öğeyi içeriyorsa, aksi halde yanlış olursa, bu yöntem doğru olarak döner. Dikkat edilmesi gereken nokta, b1 ve b2 argümanlarında hem Karşılaştırılabilir hem de Koleksiyon yöntemlerini çağırabileceğinizdir.
Geçen gün örnek başlatıcılar tarafından şaşırdım. Bazı kod katlanmış yöntemleri siliyordu ve birden çok örnek başlatıcıları oluşturma sona erdi:
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
Yöntemin yürütülmesi şunları görüntüler:
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
Birden fazla kurucuya sahipseniz ve ortak koda ihtiyacınız varsa bunlar yararlı olacaktır
Ayrıca sınıflarınızı başlatmak için sözdizimsel şeker sağlarlar:
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 +, birçok aracın üstünde güzel bir GUI olan VisualVM (bin / jvisualvm.exe) adlı bir uygulama içerir. JConsole'den daha kapsamlı görünüyor.
Java 6'dan bu yana sınıf yolu joker karakterleri.
java -classpath ./lib/* so.Main
Onun yerine
java -classpath ./lib/log4j.jar:./lib/commons-codec.jar:./lib/commons-httpclient.jar:./lib/commons-collections.jar:./lib/myApp.jar so.Main
Bkz. Http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html
Çoğu kişi için Java geliştirici pozisyonları için röportaj yaptığım bloklar çok şaşırtıcı. İşte bir örnek:
// 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'da sadece bir anahtar kelime olduğunu kim söyledi ? :)
JDK 1.5'ten beri yürürlükte olan kovaryant dönüş türlerine ne dersiniz ? Unsexy bir ekleme olduğu için oldukça zayıf bir şekilde duyuruluyor, ancak anladığım kadarıyla, jeneriklerin çalışması için kesinlikle gerekli.
Temel olarak, derleyici artık bir alt sınıfın geçersiz kılınmış bir yöntemin dönüş türünü orijinal yöntemin dönüş türünün bir alt sınıfı olması için daraltmasına izin vermektedir. Bu yüzden buna izin verilir:
class Souper {
Collection<String> values() {
...
}
}
class ThreadSafeSortedSub extends Souper {
@Override
ConcurrentSkipListSet<String> values() {
...
}
}
Alt sınıfın values
yöntemini çağırabilir ve aşağı döküm yapmak zorunda kalmadan güvenli Set
bir String
s sıralaması elde edebilirsinizConcurrentSkipListSet
.
Son olarak bir blokta kontrolün aktarılması herhangi bir istisnayı ortadan kaldırır. Aşağıdaki kod RuntimeException kuralını atmaz - kaybolur.
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;
}
}
Gönderen http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html
Hiç kimsenin null olup olmadığını kontrol etmenin gerekli olmadığı bir şekilde uygulandığından bahsetmediğini görmedim.
Onun yerine:
if( null != aObject && aObject instanceof String )
{
...
}
sadece kullan:
if( aObject instanceof String )
{
...
}
free
da delete
ing veya ing önce null olup olmadığını kontrol etmektir . Böyle temel bir kavram.
Numaralandırmalarda yöntemlere ve kuruculara izin vermek beni şaşırttı. Örneğin:
enum Cats {
FELIX(2), SHEEBA(3), RUFUS(7);
private int mAge;
Cats(int age) {
mAge = age;
}
public int getAge() {
return mAge;
}
}
Hatta, belirli bir enum değerinin yöntemleri geçersiz kılmasına izin veren bir "sabit özgül sınıf gövdesi" bile olabilir.
Daha fazla belge burada .
mAge
nihai olmalı. Sekmelerde nihai olmayan felds için nadiren bir neden vardır.
Genel yöntemler için tip parametreleri açıkça şu şekilde belirtilebilir:
Collections.<String,Integer>emptyMap()
public static <T> T foo(T t)
. Daha sonraClass.<Type>foo(t);
return set1.equals(set2) ? new ArrayList<String>(set1) : Collections.<String>emptyList()
. Basit bir Collections.emptyMap () yönteminin derleme hatası vereceği bazı yöntem çağrıları için de yararlıdır.
Bir arabirimi uygulamak için numaralandırmaları kullanabilirsiniz.
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: Yıllar sonra ....
Bu özelliği burada kullanıyorum
public enum AffinityStrategies implements AffinityStrategy {
Bir arayüz kullanarak, geliştiriciler kendi stratejilerini tanımlayabilirler. Bir enum
araç kullanarak, bunlardan inşa edilmiş (beş kişilik) bir koleksiyon tanımlayabilirim.
Java 1.5'ten itibaren Java'nın değişken değişkenlik işlevleri yazmak için çok daha temiz bir sözdizimi vardır. Yani, sadece bir diziyi geçmek yerine, aşağıdakileri yapabilirsiniz
public void foo(String... bars) {
for (String bar: bars)
System.out.println(bar);
}
barlar otomatik olarak belirtilen türde diziye dönüştürülür. Büyük bir galibiyet değil, yine de bir galibiyet.
En sevdiğim: tüm iş parçacığı yığın izlerini standart çıktıya dök.
windows: CTRL- Breakjava cmd / konsol pencerenizde
unix: kill -3 PID
Break
anahtarı olduğunu öğrettin .
Birkaç kişi örnek başlatıcıları hakkında yayın yaptı, işte bunun için iyi bir kullanım:
Map map = new HashMap() {{
put("a key", "a value");
put("another key", "another value");
}};
Hızlı ve basit bir şey yapıyorsanız haritaları başlatmanın hızlı bir yoludur.
Veya hızlı bir salınım çerçevesi prototipi oluşturmak için kullanın:
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 );
Tabii ki istismar edilebilir:
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");
}
});
}});
}});
}};
Dinamik proxy'ler (1.3'te eklenmiştir) çalışma zamanında bir arabirime uyan yeni bir tür tanımlamanıza olanak tanır. Şaşırtıcı sayıda kez kullanışlıdır.
son başlatma ertelenebilir.
Karmaşık bir mantık dönüş değerleri akışı ile bile her zaman ayarlanmış olmasını sağlar. Bir vakayı kaçırmak ve yanlışlıkla null döndürmek çok kolaydır. Null değerinin geri döndürülmesini imkansız kılmaz, sadece bilerek yapıldığı açıktır:
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'nın bir başka "gözden kaçan" özelliğinin JVM olduğunu düşünüyorum. Muhtemelen mevcut olan en iyi VM'dir. Ve birçok ilginç ve kullanışlı dili (Jython, JRuby, Scala, Groovy) destekler. Tüm bu diller kolayca ve sorunsuz bir şekilde işbirliği yapabilir.
Yeni bir dil tasarlarsanız (scala durumunda olduğu gibi) hemen mevcut tüm kütüphanelere sahip olursunuz ve bu nedenle diliniz en başından itibaren "yararlıdır".
Tüm bu diller HotSpot optimizasyonlarını kullanır. VM çok iyi izlenebilir ve hata ayıklanabilir.
Anonim bir alt sınıf tanımlayabilir ve herhangi bir arabirim uygulamasa bile doğrudan bir yöntemi çağırabilirsiniz.
new Object() {
void foo(String s) {
System.out.println(s);
}
}.foo("Hello");
start()
) çağrılan yöntem alt sınıfta tanımlanmamıştır ...
AsList yöntem java.util.Arrays
varargs, jenerik yöntem ve Autoboxing güzel bir kombinasyonunu sağlar:
List<Integer> ints = Arrays.asList(1,2,3);
Arrays.asList
Olabildiğince olağandışı özelliği vardır set()
unsurları değil add()
ya remove()
. Bu yüzden , listenin değiştirilip değiştirilemeyeceğine bağlı olarak genellikle bir new ArrayList(...)
veya Collections.unmodifiableList(...)
a'ya sararım.
Kullanılması Bu bir iç sınıftan sınıfa içeren alanları / yöntemleri erişmek için anahtar kelime. Aşağıda, oldukça tutarlı bir örnek olarak, anonim iç sınıftan konteyner sınıfının sortAscending alanını kullanmak istiyoruz. Bunun yerine ContainerClass.this.sortAscending kullanmak hile yapar.
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
.
Gerçekten bir özellik değil, son zamanlarda bazı Web sayfalarında keşfettiğim eğlenceli bir numara:
class Example
{
public static void main(String[] args)
{
System.out.println("Hello World!");
http://Phi.Lho.free.fr
System.exit(0);
}
}
geçerli bir Java programıdır (uyarı oluşturmasına rağmen). Nedenini göremiyorsanız Gregory'nin cevabına bakınız! ;-) Peki, burada vurgulanan sözdizimi de bir ipucu veriyor!
Bu tam olarak "gizli özellikler" değildir ve çok kullanışlı değildir, ancak bazı durumlarda son derece ilginç olabilir:
Sınıf sun.misc.Unsafe - Java'da doğrudan bellek yönetimi uygulamanıza izin verir (hatta kendi kendini değiştiren Java kodu yazabilirsiniz) bu çok denerseniz):
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);
}
};
}
Gizli gibi Salıncak I çalışırken Ctrl- Shift- F1özellik.
Geçerli pencerenin bileşen ağacını döker.
(Bu tuş vuruşunu başka bir şeye bağlamadığınız varsayılarak.)
Oyum , eşzamanlı koleksiyonları ve esnek yöneticileri ile java.util.concurrent'e gidiyor . DelayQueue, öğelerin belirli bir gecikmeden sonra kullanıma sunulduğu kişisel favorim.
java.util.Timer ve TimerTask güvenle durdurulabilir.
Ayrıca, tam olarak gizli değil, tarih ve saat ile ilgili diğer sınıflardan farklı bir pakette. java.util.concurrent.TimeUnit nanosaniye, mikrosaniye, milisaniye ve saniye arasında dönüştürme yaparken kullanışlıdır.
Normal bazı Değer 1 * 1000 veya Bazı Değer / 1000'den çok daha iyi okunur.
CountDownLatch
ve CyclicBarrier
- çok yararlı!
Dil düzeyinde onay anahtar kelimesi.
Java dilinin bir parçası değil, Sun'ın JDK'sı ile gelen javap sökücü yaygın olarak bilinmemekte veya kullanılmamaktadır.
1.5 için for-each döngü yapısının eklenmesi. Ben <3.
// For each Object, instantiated as foo, in myCollection
for(Object foo: myCollection) {
System.out.println(foo.toString());
}
Yuvalanmış örneklerde kullanılabilir:
for (Suit suit : suits)
for (Rank rank : ranks)
sortedDeck.add(new Card(suit, rank));
For-each yapısı, yineleyici yerine dizin değişkenini gizlediği diziler için de geçerlidir. Aşağıdaki yöntem, bir int dizisindeki değerlerin toplamını döndürür:
// Returns the sum of the elements of a
int sum(int[] a) {
int result = 0;
for (int i : a)
result += i;
return result;
}
i
Çoğu insan i bir dizi öğesi değil, bir dizin olmasını beklendiği gibi burada kullanarak süper kafa karıştırıcı olduğunu düşünüyorum .
kişisel olarak java.lang.Void
çok geç keşfedilen - jenerikler ile birlikte kod okunabilirliğini artırır, örn.Callable<Void>