Caratteristiche nascoste di Java


Dopo aver letto Caratteristiche nascoste di c# mi sono chiesto, Quali sono alcune delle caratteristiche nascoste di Java?

 295
Author: grom, 2008-08-19

30 answers

L'inizializzazione della doppia parentesi graffa mi ha colto di sorpresa qualche mese fa, quando l'ho scoperta per la prima volta, non ne ho mai sentito parlare prima.

ThreadLocals non sono in genere così ampiamente conosciuti come un modo per memorizzare lo stato per thread.

Dal momento che JDK 1.5 Java ha avuto strumenti di concorrenza estremamente ben implementati e robusti oltre ai semplici blocchi, vivono in java.util.concurrent e un esempio particolarmente interessante è java.util.simultaneo.subpackage atomico che contiene primitive thread-safe che implementano l'operazione compare-and-swap e possono essere mappate alle versioni di queste operazioni supportate dall'hardware nativo.

 432
Author: Boris Terzic, 2012-05-10 11:47:01

Unione congiunta nella varianza dei parametri di tipo:

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

Ad esempio, se si desidera prendere un parametro che sia sia comparabile che una raccolta:

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

Questo metodo artificioso restituisce true se le due raccolte date sono uguali o se una di esse contiene l'elemento dato, altrimenti false. Il punto da notare è che è possibile richiamare metodi sia Comparabili che di raccolta sugli argomenti b1 e b2.

 279
Author: Apocalisp, 2009-08-11 16:13:33

Sono rimasto sorpreso dagli inizializzatori di istanze l'altro giorno. Stavo cancellando alcuni metodi piegati in codice e ho finito per creare più inizializzatori di istanze:

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

L'esecuzione del metodo main mostrerà:

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

Immagino che questi sarebbero utili se avessi più costruttori e avessi bisogno di codice comune

Forniscono anche zucchero sintattico per inizializzare le classi:

List<Integer> numbers = new ArrayList<Integer>(){{ add(1); add(2); }};

Map<String,String> codes = new HashMap<String,String>(){{ 
  put("1","one"); 
  put("2","two");
}};
 220
Author: David Carlson, 2011-10-13 12:18:19

JDK 1.6_07+ contiene un'app chiamata VisualVM (bin/jvisualvm.exe) questa è una bella GUI in cima a molti degli strumenti. Sembra più completo di JConsole.

 201
Author: Kevin Wong, 2008-09-11 01:15:19

Classpath jolly da Java 6.

java -classpath ./lib/* so.Main

Invece di

java -classpath ./lib/log4j.jar:./lib/commons-codec.jar:./lib/commons-httpclient.jar:./lib/commons-collections.jar:./lib/myApp.jar so.Main

Vedere http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html

 173
Author: crowne, 2009-12-07 11:59:37

Per la maggior parte delle persone che intervista per le posizioni degli sviluppatori Java i blocchi etichettati sono molto sorprendenti. Ecco un esempio:

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

Chi ha detto che goto in java è solo una parola chiave? :)

 156
Author: Georgy Bolyuba, 2009-05-12 03:17:42

Che ne dici di tipi di ritorno covarianti che sono in vigore da JDK 1.5? È piuttosto poco pubblicizzato, in quanto è un'aggiunta poco sexy, ma a quanto ho capito, è assolutamente necessario che i generici funzionino.

Essenzialmente, il compilatore ora consente a una sottoclasse di restringere il tipo di ritorno di un metodo sovrascritto per essere una sottoclasse del tipo di ritorno del metodo originale. Quindi questo è permesso:

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

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

È possibile chiamare il metodo values della sottoclasse e ottenere un thread ordinato sicuro Set di String s senza dover down cast al ConcurrentSkipListSet.

 144
Author: serg10, 2008-08-29 19:44:26

Non ho visto nessuno menzionare instanceof implementato in modo tale che il controllo di null non sia necessario.

Invece di:

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

Basta usare:

if( aObject instanceof String )
{
    ...
}
 142
Author: Cadet Pirx, 2009-01-19 15:01:05

Il trasferimento del controllo in un blocco finally elimina qualsiasi eccezione. Il seguente codice non genera RuntimeException -- è perso.

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

Da http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html

 142
Author: James A. N. Stauffer, 2010-03-03 14:56:20

Consentire metodi e costruttori nelle enumerazioni mi ha sorpreso. Ad esempio:

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

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

Puoi persino avere un "corpo di classe specifico costante" che consente a un valore enum specifico di sovrascrivere i metodi.

Più documentazione qui .

 134
Author: Adrian Mouat, 2008-09-09 21:10:31

I parametri di tipo per i metodi generici possono essere specificati esplicitamente in questo modo:

Collections.<String,Integer>emptyMap()
 121
Author: Kevin Wong, 2008-09-11 02:09:12

È possibile utilizzare enum per implementare un'interfaccia.

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

MODIFICA: Anni dopo....

Io uso questa funzione qui

public enum AffinityStrategies implements AffinityStrategy {

Https://github.com/peter-lawrey/Java-Thread-Affinity/blob/master/src/main/java/vanilla/java/affinity/AffinityStrategies.java

Utilizzando un'interfaccia, gli sviluppatori possono definire le proprie strategie. Usare un enum significa che posso definire una collezione (di cinque) costruita in quelle.

 112
Author: Peter Lawrey, 2012-03-05 09:18:22

A partire da Java 1.5, Java ora ha una sintassi molto più pulita per scrivere funzioni di arity variabile. Quindi, invece di passare solo un array, ora puoi fare quanto segue

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

Bars viene automaticamente convertito in array del tipo specificato. Non una grande vittoria, ma una vittoria comunque.

 104
Author: Paul Wicks, 2008-11-03 17:02:46

Il mio preferito: scarica tutte le tracce dello stack di thread su standard out.

Finestre: CTRL-Interrompi nella finestra java cmd/console

Unix: kill -3 PID

 93
Author: Chris Mazzola, 2009-06-30 09:14:56

Un paio di persone hanno pubblicato su inizializzatori di istanze, ecco un buon uso per questo:

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

È un modo rapido per inizializzare le mappe se stai solo facendo qualcosa di semplice e veloce.

O usarlo per creare un prototipo di frame swing rapido:

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

Naturalmente può essere abusato:

    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");
                        }
                     });
                 }});
        }});
    }};
 89
Author: OscarRyz, 2009-11-27 08:06:12

I proxy dinamici (aggiunti in 1.3) consentono di definire un nuovo tipo in fase di runtime conforme a un'interfaccia. È tornato utile un numero sorprendente di volte.

 88
Author: jodonnell, 2012-05-10 13:14:12

L'inizializzazione finale può essere posticipata.

Fa in modo che anche con un flusso complesso di valori di ritorno logica sono sempre impostati. È troppo facile perdere un caso e restituire null per caso. Non rende impossibile restituire null, solo ovvio che è apposta:

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;
}
 82
Author: Allain Lalonde, 2009-01-07 18:29:42

Penso che un'altra caratteristica "trascurata" di java sia la JVM stessa. È probabilmente la migliore VM disponibile. E supporta un sacco di lingue interessanti e utili (Jython, JRuby, Scala, Groovy). Tutte queste lingue possono facilmente e senza soluzione di continuità cooperare.

Se si progetta una nuova lingua (come nel caso scala) si hanno immediatamente tutte le librerie esistenti disponibili e la lingua è quindi "utile" fin dall'inizio.

Tutte queste lingue fanno uso dell'HotSpot ottimizzazione. La VM è molto ben monitorata e debuggabile.

 62
Author: Mo., 2008-08-19 16:47:35

È possibile definire una sottoclasse anonima e chiamare direttamente un metodo su di esso anche se non implementa interfacce.

new Object() {
  void foo(String s) {
    System.out.println(s);
  }
}.foo("Hello");
 58
Author: Ron, 2009-06-22 01:17:28

Il metodo asList in java.util.Arrays consente una bella combinazione di varargs, metodi generici e autoboxing:

List<Integer> ints = Arrays.asList(1,2,3);
 56
Author: Bruno De Fraine, 2008-09-15 15:55:15

Usando questa parola chiave per accedere ai campi/metodi di contenere la classe da una classe interna. Nell'esempio seguente, piuttosto artificioso, vogliamo utilizzare il campo sortAscending della classe container dalla classe interna anonima. Utilizzando ContainerClass.questo.sortAscending invece di questo.sortAscending fa il trucco.

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;
}
}
 53
Author: Tahir Akhtar, 2008-09-19 13:02:49

Non proprio una caratteristica, ma un trucco divertente che ho scoperto di recente in qualche pagina Web:

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

    System.exit(0);
  }
}

È un programma Java valido (anche se genera un avviso). Se non capisci perché, vedi la risposta di Gregory! ;- ) Bene, l'evidenziazione della sintassi qui dà anche un suggerimento!

 52
Author: PhiLho, 2008-09-17 11:39:29

Questo non è esattamente" caratteristiche nascoste " e non molto utile, ma può essere estremamente interessante in alcuni casi:
Classe sole.varie.Unsafe-ti permetterà di implementare direct memory management in Java (puoi persino scrivere codice Java auto-modificante con questo se ci provi molto):

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);
        }
    };
}
 46
Author: Das, 2008-09-19 13:35:12

Quando si lavora in Swing mi piace il Ctrl nascosto - Maiusc - F1 caratteristica.

Scarica l'albero dei componenti della finestra corrente.
(Supponendo che tu non abbia associato quel tasto a qualcos'altro.)

 42
Author: Devon_C_Miller, 2010-03-23 18:44:24

Ogni file di classe inizia con il valore esadecimale 0xCAFEBABE per identificarlo come bytecode JVM valido.

(Spiegazione)

 40
Author: Dolph, 2010-02-19 05:29:42

Il mio voto va a java.util.concurrent con le sue raccolte simultanee e gli esecutori flessibili che consentono tra gli altri pool di thread, attività pianificate e attività coordinate. Il DelayQueue è il mio preferito, dove gli elementi sono resi disponibili dopo un ritardo specificato.

Java.util.Timer e TimerTask possono tranquillamente essere messi a riposo.

Inoltre, non esattamente nascosto ma in un pacchetto diverso dalle altre classi relative a data e ora. Java.util.simultaneo.TimeUnit è utile per la conversione tra nanosecondi, microsecondi, millisecondi e secondi.

Legge molto meglio del solito someValue * 1000 o someValue / 1000.

 38
Author: stili, 2008-12-04 19:51:57

A livello di linguaassert parola chiave.

 37
Author: Mark Cidade, 2008-08-19 01:51:22

Non fa parte del linguaggio Java, ma il disassemblatore javap fornito con JDK di Sun non è ampiamente conosciuto o utilizzato.

 37
Author: Binil Thomas, 2008-09-10 17:20:11

L'aggiunta del costrutto for-each loop in 1.5. I

// For each Object, instantiated as foo, in myCollection
for(Object foo: myCollection) {
  System.out.println(foo.toString());
}

E può essere utilizzato in istanze nidificate:

for (Suit suit : suits)
  for (Rank rank : ranks)
    sortedDeck.add(new Card(suit, rank));

Il costrutto for-each è applicabile anche agli array, dove nasconde la variabile index anziché l'iteratore. Il seguente metodo restituisce la somma dei valori in un array int:

// Returns the sum of the elements of a
int sum(int[] a) {
  int result = 0;
  for (int i : a)
    result += i;
  return result;
}

Collegamento alla documentazione Sun

 36
Author: 18Rabbit, 2008-09-16 18:35:19

Ho scoperto personalmente java.lang.Void molto tardi improves migliora la leggibilità del codice in combinazione con i generici, ad esempio Callable<Void>

 34
Author: Rahel Lüthy, 2009-02-17 13:25:09