Fonctionnalités cachées de Java


Après avoir luLes fonctionnalités cachées de C# Je me suis demandé, Quelles sont certaines des fonctionnalités cachées de Java?

 295
Author: grom, 2008-08-19

30 answers

L'initialisation de Double Accolade m'a pris par surprise il y a quelques mois lorsque je l'ai découverte pour la première fois, je n'en avais jamais entendu parler auparavant.

ThreadLocals ne sont généralement pas aussi largement connus comme un moyen de stocker l'état par thread.

Depuis que JDK 1.5 Java a eu des outils de concurrence extrêmement bien implémentés et robustes au-delà des verrous, ils vivent dans java.util.concurrent et un exemple particulièrement intéressant est le java.util.simultané.atomic sous-paquet qui contient des primitives thread-safe qui implémentent l'opération compare-and-swap et peuvent être mappées aux versions matérielles natives réelles de ces opérations.

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

Union conjointe dans la variance des paramètres de type:

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

Par exemple, si vous voulez prendre un paramètre à la fois Comparable et une 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);
}

Cette méthode artificielle renvoie true si les deux collections données sont égales ou si l'une d'entre elles contient l'élément donné, sinon false. Le point à noter est que vous pouvez invoquer des méthodes de Comparable et de Collection sur les arguments b1 et b2.

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

J'ai été surpris par les initialiseurs d'instance l'autre jour. Je supprimais certaines méthodes pliées en code et j'ai fini par créer plusieurs initialiseurs d'instance:

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'exécution de la méthode main affichera:

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

Je suppose que ceux-ci seraient utiles si vous aviez plusieurs constructeurs et que vous aviez besoin de code commun

Ils fournissent également du sucre syntaxique pour initialiser vos classes:

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+ contient une application appelée VisualVM (bin/jvisualvm.exe) c'est une belle interface graphique au-dessus de la plupart des outils. Il semble plus complet que JConsole.

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

Jokers Classpath depuis Java 6.

java -classpath ./lib/* so.Main

Au Lieu de

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

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

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

Pour la plupart des gens que j'interviewe pour les postes de développeur Java, les blocs étiquetés sont très surprenants. Voici un exemple:

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

Qui a dit que goto en java n'est qu'un mot-clé? :)

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

Que diriez-vous de types de retour covariants qui sont en place depuis JDK 1.5? C'est assez mal médiatisé, car c'est un ajout peu sexy, mais si je comprends bien, il est absolument nécessaire que les génériques fonctionnent.

Essentiellement, le compilateur permet maintenant à une sous-classe de réduire le type de retour d'une méthode remplacée pour être une sous-classe du type de retour de la méthode d'origine. Ceci est donc autorisé:

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

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

Vous pouvez appeler la méthode values de la sous-classe et obtenir un thread trié sûr Setde Strings sans avoir à lancer vers le bas au ConcurrentSkipListSet.

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

Je n'ai vu personne mentionner instanceof implémenté de telle manière que la vérification de null n'est pas nécessaire.

Au Lieu de:

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

Utilisez simplement:

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

Le transfert de contrôle dans un bloc finally supprime toute exception. Le code suivant ne lance pas RuntimeException it il est perdu.

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

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

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

Autoriser les méthodes et les constructeurs dans les énumérations m'a surpris. Par exemple:

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

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

Vous pouvez même avoir un "corps de classe spécifique constant" qui permet à une valeur d'énumération spécifique de remplacer les méthodes.

Plus de documentation ici.

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

Les paramètres de type pour les méthodes génériques peuvent être spécifiés explicitement comme ceci:

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

Vous pouvez utiliser enums pour implémenter une interface.

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: Des années plus tard....

J'utilise cette fonctionnalité ici

public enum AffinityStrategies implements AffinityStrategy {

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

En utilisant une interface, les développeurs peuvent définir leurs propres stratégies. L'utilisation d'un enum signifie que je peux définir une collection (de cinq) intégrée.

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

À partir de Java 1.5, Java a maintenant une syntaxe beaucoup plus propre pour écrire des fonctions d'arité variable. Donc, au lieu de simplement passer un tableau, vous pouvez maintenant faire ce qui suit

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

Bars est automatiquement converti en tableau du type spécifié. Pas une énorme victoire, mais une victoire quand même.

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

Mon préféré: videz toutes les traces de la pile de threads en standard.

Windows: CTRL-Pause - dans votre java cmd/fenêtre de console

Unix: kill -3 PID

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

Quelques personnes ont posté sur les initialiseurs d'instance, voici une bonne utilisation pour cela:

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

Est un moyen rapide d'initialiser les cartes si vous faites simplement quelque chose de rapide et simple.

Ou l'utiliser pour créer un prototype de cadre swing rapide:

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

Bien sûr, il peut être abusé:

    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

Les proxies dynamiques (ajoutés dans la version 1.3) vous permettent de définir un nouveau type à l'exécution conforme à une interface. C'est utile un nombre surprenant de fois.

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

L'initialisation finale peut être reportée.

Il s'assure que même avec un flux complexe de valeurs de retour logiques sont toujours définies. Il est trop facile de manquer un cas et de retourner null par accident. Cela ne rend pas le retour de null impossible, juste évident que c'est exprès:

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

Je pense qu'une autre fonctionnalité "négligée" de java est la JVM elle-même. C'est probablement la meilleure machine virtuelle disponible. Et il prend en charge beaucoup de langages intéressants et utiles (Jython, JRuby, Scala, Groovy). Toutes ces langues peuvent facilement et de manière transparente coopérer.

Si vous concevez un nouveau langage (comme dans le cas scala), vous avez immédiatement toutes les bibliothèques existantes disponibles et votre langage est donc "utile" dès le début.

Toutes ces langues utilisent le HotSpot optimisation. La machine virtuelle est très bien surveillée et déboguable.

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

Vous pouvez définir une sous-classe anonyme et appeler directement une méthode dessus même si elle n'implémente aucune interface.

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

La méthodeasList dans java.util.Arrays permet une belle combinaison de varargs, de méthodes génériques et d'autoboxing:

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

En utilisant ce mot-clé pour accéder aux champs/méthodes de contenant une classe à partir d'une classe interne. Dans ci-dessous, un exemple plutôt artificiel, nous voulons utiliser le champ sortAscending de la classe container de la classe interne anonyme. Utilisation de ContainerClass.ce.sortAscending au lieu de cela.sortAscending fait l'affaire.

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

Pas vraiment une fonctionnalité, mais un truc amusant que j'ai découvert récemment dans une page Web:

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

    System.exit(0);
  }
}

Est un programme Java valide (bien qu'il génère un avertissement). Si vous ne voyez pas pourquoi, voyez la réponse de Gregory! ;- ) Eh bien, la coloration syntaxique ici donne aussi un indice!

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

Ce n'est pas exactement "cachés" et pas très utile, mais peut être très intéressant dans certains cas:
La classe soleil.misc.Unsafe-vous permettra d'implémenter direct memory management en Java (vous pouvez même écrire du code Java auto-modifiant avec cela si vous essayez beaucoup):

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

Lorsque vous travaillez dans les Swing j'aime cachés Ctrl - Maj - F1 fonctionnalité.

Il vide l'arborescence des composants de la fenêtre en cours.
(En supposant que vous n'avez pas lié cette frappe à autre chose.)

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

Chaque fichier de classe commence par la valeur hexadécimale 0xCAFEBABE pour l'identifier comme bytecode JVM valide.

(Explication)

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

Mon vote va à java.util.concurrent avec ses collections simultanées et ses exécuteurs flexibles permettant entre autres des pools de threads, des tâches planifiées et des tâches coordonnées. Le DelayQueue est mon favori personnel, où les éléments sont mis à disposition après un délai spécifié.

Java.util.Timer et TimerTask peuvent être mis au repos en toute sécurité.

Aussi, pas exactement caché mais dans un paquet différent des autres classes liées à la date et à l'heure. Java.util.simultané.TimeUnit est utile lors de la conversion entre nanosecondes, microsecondes, millisecondes et secondes.

, Il lit beaucoup mieux que l'habituel someValue * 1000 ou someValue / 1000.

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

Niveau de langueassert mot clé.

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

Ne fait pas vraiment partie du langage Java, mais le désassembleur javap qui vient avec le JDK de Sun n'est pas largement connu ou utilisé.

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

L'ajout de la construction de boucle for-each en 1.5. I

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

Et peut être utilisé dans des instances imbriquées:

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

La construction for-each est également applicable aux tableaux, où elle masque la variable d'index plutôt que l'itérateur. La méthode suivante renvoie la somme des valeurs dans un tableau int:

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

Lien vers la documentation de Sun

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

J'ai personnellement découvert java.lang.Void très tard improves améliore la lisibilité du code en conjonction avec les génériques, par exemple Callable<Void>

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