IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

Oracle lance une nouvelle tentative pour intégrer la modularité à Java


Sujet :

Java

  1. #21
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    Ah oui en effet, après avoir vu ces exemples je comprends mieux... mais comme dit plus haut, au niveau de l'implémentation, les ArrayList (il me semble) se servent des tableaux. Il y aura toujours des tableaux, c'est un moyen d'optimiser le tri.
    Les tableaux c'est surtout un moyen de stocker des données, mais leur héritage bizarroïde les rendent "unsafe".

    Perso j'aurais tendance à utiliser des List<T>, même si au final c'est un simple wrapper autour d'un tableau (comme avec Arrays.asList("a", "b", "c")).

    Mais on moins on a une API propre, un code typesafe et l'accès à toutes les APIs des Collections !



    Citation Envoyé par Gugelhupf Voir le message
    Comme en C++11 (mais les tableaux existent toujours).
    Les tableaux existent toujours... pour assurer la rétrocompatibilité

    On en revient au même point


    a++

  2. #22
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Sinon a propos des Generics "reified".
    Il y a une autre limitation qui n'a pas été mise en avant, c'est que cela complique la covariance/contravariance des types Generics.


    Déjà ce principe n'est apparut que dans C# 4.0, alors que les Generics datent de C# 2.0, mais il est également limité par rapport à Java.



    Pour rappel la covariance/contravariance permet d'utiliser des types Generics plus "vague", en remplacement du type paramétré.
    En Java on dispose d'une syntaxe spéciale pour cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	// Covariance
    	List<? extends Object> objects = new ArrayList<String>();
     
    	// Contravariance :
    	List<? super Double> doubles = new ArrayList<Number>();
    Grosso-modo avec la covariance on a seulement accès aux méthodes retournant le type paramétré, et avec la contravariance on a accès aux méthodes acceptant un type paramétré en paramètre.



    Avec C# 4.0 ce n'est pas possible tel quel, car il y a plusieurs limitations inexistantes en Java :
    • Cela ne peut s'appliquer que sur des interfaces Generics.
      Impossible de l'utiliser tel quel sur une classe Generics (à moins de lui faire implémenter une interface covariante/contravariante qu'on utilisera).
    • La notion de covariante/contravariante doit être définit dans la définition de l'interface elle même (via les mot-clef in/out dans la définition du paramétrage).
      Si l'interface ne le prévoit pas on ne peut pas l'utiliser.
    • Ces interfaces doivent respecter des contraintes quand à l'utilisation du type paramétré.
      Un type paramétré covariant ne pourra pas être utilisé en paramètre d'une méthode de l'interface.
      Un type paramétré contravariant ne pourra pas être utilisé en type de retour d'une méthode de l'interface.



    a++

  3. #23
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 740
    Points
    3 740
    Billets dans le blog
    12
    Par défaut
    Bonsoir,

    C'est drôle parce que plus haut tu faisais référence aux méthodes wait()/notify(), mais je trouve qu'il y a tellement de chose à casser dans Java :

    • Visibilité package ou par défaut agaçante => Mettre en "public" par défaut lorsqu’on ne précise pas le type d’accès.
    • Generic qui cast en Object => problèmes précédemment cités à corriger.
    • Supprimer les joker, covariance et contravariance, qui selon moi gâche plus la lisibilité du code qu'autre chose (voir exemple plus bas).
    • Supprimer l’interface Serializable et remplacer par une annotation @Serializable (pourquoi une classe Enfant devrait être serialisable si la classe Parent l’est ?).
    • Classe locale => A supprimer, on peut largement s’en passer.
    • Bloc static => A supprimer, on peut largement s’en passer. Je sais qu'on s'en sert pour initialiser un driver depuis les débuts de JDBC, mais cette technique dépassé je trouve. Aussi on peut facilement initialiser ses attributs static depuis la déclaration ou le constructeur.
    • Anonymous initializer => Juste utile pour initialiser les classes anonymes, mais on peut largement s’en passer.
    • Utiliser un nom de méthode uniforme pour les pattern Singleton (ex: getInstance() au lieu de Runtime.getRuntime() etc…).
    • Pour le pattern Observer/Observable, Observable est une classe, du coup une classe Observable ne peut pas hériter d'une autre, Observable aurait du être une Interface...
    • Supprimer les Wrapper => des variables primitives « orientés objets » pour avoir un langage full objet (prévu pour une version future de Java).
    • Limiter l'utilisation de la classe "fourre-tout" Object dans le code, et privilégier la généricité... Oui après Object reste toujours utile pour les méthodes comme equals() et hashcode()...
    • Créer une sucre syntaxique qui remplace System.out.println() par println()


    Je peux paraître extrémiste, mais en fait, je trouve que tout ce qui n'est pas/plus vraiment utile, ou pousse par la loi de Murphy le développeur à abuser de ce qui est réalisable, ne devrait pas exister.

    Exemple sur la covariance :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    public enum GameState {
        JOINING {
     
            public <B extends Board, A extends Action<B>, P extends Player<B, A>, G extends Game<B, A, P>> void joinPlayer(G game, Session session) {
                game.insertPlayer(session);
                if (game.getExpectedPlayerCount() == 0) {
                    game.setState(OPEN);
                }
            }
        },
        OPEN {
     
            public <B extends Board, A extends Action<B>, P extends Player<B, A>, G extends Game<B, A, P>> void playGame(G game) {
                game.performGame();
            }
     
            public <B extends Board, A extends Action<B>, P extends Player<B, A>, G extends Game<B, A, P>> void playTurn(G game) {
                game.performTurn();
            }
     
            public <B extends Board, A extends Action<B>, P extends Player<B, A>, G extends Game<B, A, P>> void makeAction(G game, Session session, A action) {
                game.performAction(session, action);
                if (game.isOver()) {
                    game.setState(ENDED);
                }
            }
     
        },
        ENDED {
            public <B extends Board, A extends Action<B>, P extends Player<B, A>, G extends Game<B, A, P>> void playGame(G game) {
                /* Restart the game with the same players */
                game.setState(OPEN);
            }
        };
     
        public <B extends Board, A extends Action<B>, P extends Player<B, A>, G extends Game<B, A, P>> void joinPlayer(G game, Session session) { /* Nothing to do */ }
        public <B extends Board, A extends Action<B>, P extends Player<B, A>, G extends Game<B, A, P>> void playGame(G game) { /* Nothing to do */ };
        public <B extends Board, A extends Action<B>, P extends Player<B, A>, G extends Game<B, A, P>> void playTurn(G game) { /* Nothing to do */ };
        public <B extends Board, A extends Action<B>, P extends Player<B, A>, G extends Game<B, A, P>> void makeAction(G game, Session session, A action) { /* Nothing to do */ };
    }
    PS: J'aurai aussi pu prendre un programme rempli de classes locales.

    Quelques ajouts ne feraient pas de mal :
    • Ajouter les mêmes bonus (« += », « + ») que String pour BigInteger et BigDecimal.
    • Ajout de yield
    • Ajout de SQL (un peu comme dans PowerBuilder, et pas comme cette pâle imitation de LINQ).
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  4. #24
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Je ne suis pas d'accord concernant la covariance/contravariance !
    Les supprimer rendrait les Generics pénible car il faudrait dupliquer plein de code pour pas grand chose.


    Oui le code que tu montres est affreux, mais le problème ne vient pas forcément de la fonctionnalité !
    Je veux dire je suis déjà tombé sur des méthodes avec plus de 15 paramètres. C'est encore plus affreux à lire, mais ce n'est pas pour autant qu'il faut interdire les méthodes de plus d'un paramètre


    a++

  5. #25
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    C'est drôle parce que plus haut tu faisais référence aux méthodes wait()/notify(), mais je trouve qu'il y a tellement de chose à casser dans Java.
    Je trouve que c'est un mécanisme aussi bien pensé que equals/hashCode/clone.
    Dans ce cas, ca permet d'avoir à passer une ressource supplémentaire (le lock) pour gérer la synchronisation sur une "simple" ressource. Ca évite de trimballer une (ou plusieurs) instances supplémentaires.

    Citation Envoyé par Gugelhupf Voir le message
    Visibilité package ou par défaut agaçante => Mettre en "public" par défaut lorsque l’on ne précise pas le type d’accès.
    C'est le cas pour les interfaces "par nature". Ce qui me choque plus c'est l'abscence de mot clé.

    Citation Envoyé par Gugelhupf Voir le message
    Generic qui cast en Object => problèmes précédemment cités à corriger.
    Attention ca ne caste pas nécessairement en Object, d'où l'intérêt de la covariance/contravariance.

    Citation Envoyé par Gugelhupf Voir le message
    Supprimer les joker, covariance et contravariance, qui selon moi gâche plus la lisibilité du code qu'autre chose (voir exemple plus bas).
    Définitivement non !

    Citation Envoyé par Gugelhupf Voir le message
    Supprimer l’interface Serializable et remplacer par une annotation @Serializable (pourquoi une classe Enfant devrait être serialisable si la classe Parent l’est ?).
    Pourquoi pas ... Mais ca contredirait le principe de substitution (Liskov?), sérialiser la classe mère fonctionnerait mais pas la fille ...
    Ca indique clairement que les instances de cette classe sont susceptibles d'être utilisé par un mécanisme de sérialisation.

    Citation Envoyé par Gugelhupf Voir le message
    Classe locale => A supprimer, on peut largement s’en passer.
    Ca permet de mieux contrôler la visibilité et c'est un sucre syntaxique bien utile et nécessaire pour les classes anonymes.

    Citation Envoyé par Gugelhupf Voir le message
    Bloc static => A supprimer, on peut largement s’en passer. Je sais qu'on s'en sert pour initialiser un driver depuis les débuts de JDBC, mais cette technique dépassé je trouve. Aussi on peut facilement initialiser ses attributs static depuis la déclaration ou le constructeur.
    Les blocs static ont tout de même un impact considérable, ils ne sont exécutés qu'une et une seule fois au chargement de la classe et ceux de manière thread-safe. Pour contourner, il faut passer par une classe interne (ou locale) et créer une instance de cette classe interne dans un champ static de la classe encapsulante.

    Citation Envoyé par Gugelhupf Voir le message
    Anonymous initializer => Juste utile pour initialiser les classes anonymes, mais on peut largement s’en passer.
    Clairement je préferais la définition d'un constructeur pour les classes anonymes. Mais c'est très rigolo pour faire perdre du temps ou proposer un défi au débutant en leur demandant de deviner l'ordre d'exécution des instructions.

    Citation Envoyé par Gugelhupf Voir le message
    Utiliser un nom de méthode uniforme pour les pattern Singleton (ex: getInstance() au lieu de Runtime.getRuntime() etc…).
    Ca c'est du design, rien à avoir avec le langage.

    Citation Envoyé par Gugelhupf Voir le message
    Pour le pattern Observer/Observable, Observable est une classe, du coup une classe Observable ne peut pas hériter d'une autre, Observable aurait du être une Interface...
    Jamais utilisé ... Sinon la bonne technique du Wrapper, ca marche toujours

    Citation Envoyé par Gugelhupf Voir le message
    Supprimer les Wrapper => des variables primitives « orientés objets » pour avoir un langage full objet (prévu pour une version future de Java).
    Ca pourrait être pas mal mais il faut savoir que les objects et les primitifs ne sont pas gérés de la même manière (tas/pile). Ce qui introduirait de grosses différences mémoire et CPU.

    Citation Envoyé par Gugelhupf Voir le message
    Limiter l'utilisation de la classe "fourre-tout" Object dans le code, et privilégier la généricité... Oui après Object reste toujours utile pour les méthodes comme equals() et hashcode()...
    A réfléchir mais je pense que ca pourrait être compliqué pour des choses très génériques comme les API de "lecture" (désérialisation, persitance, etc.)

    Citation Envoyé par Gugelhupf Voir le message
    Créer une sucre syntaxique qui remplace System.out.println() par println()
    Java n'est pas un langage de script, le println est donc généralement à bannir.

    Citation Envoyé par Gugelhupf Voir le message
    Ajouter les mêmes bonus (« += », « + ») que String pour BigInteger et BigDecimal.
    Number manière générale, voir de permettre la rédéfinition. Par contre impossible prévoir les effets de bord sur le code qui actuellement utilise un appel implicite à String.valueOf.
    Citation Envoyé par Gugelhupf Voir le message
    Ajout de yield
    yield me semble beaucoup moins intéressants que les closures&co. Même si je préferais des pointeurs de fonctions ou quelque chose de similaire au delegate de C#.

    Citation Envoyé par Gugelhupf Voir le message
    Ajout de SQL (un peu comme dans PowerBuilder, et pas comme cette pâle imitation de LINQ).
    Non pour la bonne et simple raison : pourquoi SQL et pas un autre ? Dans ce cas, je pense qu'il vaut mieux utiliser l'API de scripting et invoquer le moteur que l'on souhaite utiliser. Resterait à voir l'intégration du script (et l'appel au moteur) dans le source Java. Mais je reste sceptique.



    Par contre, je trouverais ultra-intéressant de faire en sorte que void soit traité comme renvoyé le type manipulé pour permettre le chaînage ou alors introduire le mot clé with de VB.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  6. #26
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Nemek Voir le message
    Je trouve que c'est un mécanisme aussi bien pensé que equals/hashCode/clone.
    Dans ce cas, ca permet d'avoir à passer une ressource supplémentaire (le lock) pour gérer la synchronisation sur une "simple" ressource. Ca évite de trimballer une (ou plusieurs) instances supplémentaires.
    Ce n'est pas le mécanisme en lui même qui pose problème, mais le fait que les méthodes wait()/notify() soit présente dans Object et donc dans tous les classes...

    Bref plutôt qu'en faire des méthodes d'instances de Object, cela aurait dû être des méthodes static d'une classe du package java.lang...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // Au lieu d'écrire :
    object.wait();
    object.notify();
     
    // On utiliserait :
    Synchronizer.wait(object);
    Synchronizer.notify(object);
    Cela permettrait d'épurer un peu la classe Object...


    Citation Envoyé par Nemek Voir le message
    Ca pourrait être pas mal mais il faut savoir que les objects et les primitifs ne sont pas gérés de la même manière (tas/pile). Ce qui introduirait de grosses différences mémoire et CPU.
    Il me semble que la suppression des primitives est prévu pour Java 10...



    Citation Envoyé par Nemek Voir le message
    yield me semble beaucoup moins intéressants que les closures&co. Même si je préferais des pointeurs de fonctions ou quelque chose de similaire au delegate de C#.
    +1 pour le yield. Même si ca peut être bien pratique dans certains cas c'est juste du sucre syntaxique.


    Pour le reste les lambdas et surtout les références de méthode permettront d'avoir quelque chose de très proche des delegate du C#.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MyButton extends JButton {
     
        public MyButton(String name) {
            super(name);
            addActionListener(this::myMethod);
        }
     
        private void myMethod(ActionEvent event) {
            // code
        }
    }
    Perso je trouve que c'est même plus puissant car il n'y a pas de type "delegate", mais une simple interface fonctionnelle (avec une seule méthode abstraite), ce qui apporte plein d'avantage :
    • C'est compatible avec plein de code existant (et les interfaces mono-méthodes sont très courantes).
    • On conserve le choix d'utiliser une méthode ou une classe implémentant l'interface (pour des trucs plus complexe).
    • Ces interfaces fonctionnelles n'ont qu'une seule méthode abstraites, mais elles peuvent avoir une API plus complète avec les méthodes par défaut.


    Citation Envoyé par Nemek Voir le message
    Non pour la bonne et simple raison : pourquoi SQL et pas un autre ? Dans ce cas, je pense qu'il vaut mieux utiliser l'API de scripting et invoquer le moteur que l'on souhaite utiliser. Resterait à voir l'intégration du script (et l'appel au moteur) dans le source Java. Mais je reste sceptique.
    Ca pourrait être pratique dans certains cas.
    J'utilise GWT et ils ont un compilateur spécifique qui permet d'intégrer du JavaScript dans une classe Java (en le faisant passer pour une méthode native).
    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public native String hostname() /*-{
        // code javascript
        return location.hostname;
    }-*/;
    Ce serait pratique de pouvoir faire des truc comme cela en vrai Java via l'API de Scripting...



    a++

  7. #27
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 740
    Points
    3 740
    Billets dans le blog
    12
    Par défaut
    Bonsoir,

    @Namek
    C'est le cas pour les interfaces "par nature". Ce qui me choque plus c'est l'abscence de mot clé.
    On peut forcer l'emploi du mot-clé "public" alors ?



    Pourquoi pas ... Mais ca contredirait le principe de substitution (Liskov?), sérialiser la classe mère fonctionnerait mais pas la fille ...
    Ca indique clairement que les instances de cette classe sont susceptibles d'être utilisé par un mécanisme de sérialisation.
    Lorsque je veux créer une classe X héritant d'une classe X+1 d'une lib qui ne m'appartient pas, je ne sais pas si dans la hiérarchie une classe X+n implémente Serializable, et je ne pense pas forcément à créer une classe X qui est Serializable. Du coup je me retrouve avec une classe implémentant par défaut Serializable sans l'être vraiment. Si C# utilise l'annotation [Serializable] pour ses classes au lieu d'implémenter une interface, c'est qu'il doit y avoir une raison.



    Ca permet de mieux contrôler la visibilité et c'est un sucre syntaxique bien utile et nécessaire pour les classes anonymes.
    Donc si je comprends bien, sans classes locales, il ne pourrait pas y avoir de classe Anonyme ?



    Les blocs static ont tout de même un impact considérable, ils ne sont exécutés qu'une et une seule fois au chargement de la classe et ceux de manière thread-safe. Pour contourner, il faut passer par une classe interne (ou locale) et créer une instance de cette classe interne dans un champ static de la classe encapsulante.
    Pourrais-tu me montrer une utilisation concrète de ce bloc dont je ne pourrais pas me passer ?



    Clairement je préferais la définition d'un constructeur pour les classes anonymes. Mais c'est très rigolo pour faire perdre du temps ou proposer un défi au débutant en leur demandant de deviner l'ordre d'exécution des instructions.
    Oui ça amuse aussi Oracle (exam certification) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class Sequence {
    Sequence() { System.out.print("c "); }
    { System.out.print("y "); }
    public static void main(String[] args) {
    new Sequence().go();
    }
    void go() { System.out.print("g "); }
    static { System.out.print("x "); }
    }
     
    /*
    What is the result?
    A) c x y g
    B) c g x y 
    C) x c y g
    D) x y c g
    E) y x c g
    F) y c g x
    */
    Source.
    Mais idem que pour le précédent, est-ce vraiment utile ?



    Ca c'est du design, rien à avoir avec le langage.
    Si on reprend avec l'exemple de PHP, qui est réputé pour avoir des noms de fonctions bizarroïde :
    Underscore versus not: strpos/str_rot13, php_uname/phpversion, base64_encode/urlencode, gettype/get_class
    “to” versus 2: ascii2ebcdic, bin2hex, deg2rad, strtolower, strtotime
    Source. Donner un nom du type getSingleton() ou getInstance() serait mieux.




    Java n'est pas un langage de script, le println est donc généralement à bannir.
    Peut-être mais pourquoi en faire autant ? ("out.").
    En C# il suffit de faire Console.Write() ou WriteLine()
    Au bout d'un moment ça devient lourd pour les tests.




    Non pour la bonne et simple raison : pourquoi SQL et pas un autre ? Dans ce cas, je pense qu'il vaut mieux utiliser l'API de scripting et invoquer le moteur que l'on souhaite utiliser. Resterait à voir l'intégration du script (et l'appel au moteur) dans le source Java. Mais je reste sceptique.
    Je peux dire oui pour tout ce que tu as dis plus haut, mais là non. Le SQL est le langage par excellence pour la fouille de données 2D (et plus de dimensions avec les extensions Microsoft comme MDX pour les cubes, bien que pas standard).
    Impossible de réinventer la roue. Certains prédisent la mort de Java d'ici 20 ans. Pour le SQL ? C'est tout bonnement impossible et ce n'est pas des couches objets comme Hibernate qui pourront faire mieux (PS: Je parle bien sur pour les requêtes de type SELECT).



    @adiGuba
    +1 pour le yield. Même si ca peut être bien pratique dans certains cas c'est juste du sucre syntaxique.
    Yield possède un comportement bien particulier. Lorsque qu'une méthode retourne une liste de valeur (ex: List<String> methode(){} ), on n'alloue pas tous les éléments de la liste en mémoire en bloc, mais juste celle d'un élément String qu'on retourne à chaque présence du mot yield.
    Par pur curiosité, je voudrais bien voir un équivalent simple en Java de yield... sans yield.



    Cordialement,
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  8. #28
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    Lorsque je veux créer une classe X héritant d'une classe X+1 d'une lib qui ne m'appartient pas, je ne sais pas si dans la hiérarchie une classe X+n implémente Serializable
    Ben si, a priori, tu le sais. Quand tu hérite d'une classe, c'est important de connaitre sa hierarchie. A moins que tu soit du genre à prendre une clase de type liste parce qu'elle te plait bien, et à t'en foutre que c'est un JList donc qu'elle hérite de toute la chierie AWT, et qu'en fait c'est un composant graphique

    C# utilise l'annotation [Serializable] pour ses classes au lieu d'implémenter une interface, c'est qu'il doit y avoir une raison.
    Il est inutile de comparer les language, chacun a des perspective différentes.


    Si je fais une classe sérialisable, contenant deux champs sérialisable, je considère qu'elle est bien faite ma classe et se sérialise correctement. Puis un gros malin, viens me substituer une classe fille non sérialisable dans un de mes champs, et zon, ma classe pourtant bien codée deviens insérialisable.


    Et plus le compilateur et les ide ont la gentilesse de bien attirer ton attention quand tu hérite d'une classe sérializable, pas d'excuses


    Donc si je comprends bien, sans classes locales, il ne pourrait pas y avoir de classe Anonyme ?
    Ben une classe anonyme, c'est une classe locale qui n'a pas de nom



    Pourrais-tu me montrer une utilisation concrète de ce bloc dont je ne pourrais pas me passer ?
    Je n'en ai pas en tête là, j'en ai utilisé je pense deux fois dans ma vie, et les deux fois pour une seule raison: impossible de faire autrement ET propre (ou j'avais l'option autrement ET moche). Je me souviens vaguement d'un cas où je devais appeler une option de config sur une librairie que je ne contrôlait pas, je ne pouvais appeler cette option que 1 et 1 seule fois, mais je devais garantir son appel avant que ma classe utilise la dite librairie. La méthode moche: toutes les méthodes synchronizées, un flag statique et si le flag pas à true on appelle la méthode de config -> Moche à lire, lent au possible



    Donner un nom du type getSingleton() ou getInstance() serait mieux.
    Oui, mais c'est assez dur de changer quelque chose qui a existé par le passé. On ne peux pas retirer l'ancienne méthode. Et rajouter une méthode Runtime.getInstance() serait aussi confus, les programmeurs commenceraient à se demander laquelle est la bonne.

    Au moins, ils ont pris un getter, c'est déjà ça de pris


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Au bout d'un moment ça devient lourd pour les tests.
    Ca fait un bail que je n'ai presque plus de System.out.println. Encore une fois, rajouter par défaut println ça va poser de gros gros problèmes de compatibilité. Comment écrire une classe ayant une méthode appelée println après ça, comment le compilateur sais laquelle appeler. Tu me dira, on pourra dire change la méthode de ton code. Ouais, mais println justement est défini dans une interface utilisée et implémentée par des chiées de programmes.....

    Enfin, les ide te permettent de taper sysout pour faire plus court, donc voilà quoi.
    Ha oui, et tu peux toujours faire un import static System.* si ça t'amuse pour écrire plus court...

  9. #29
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    Pourrais-tu me montrer une utilisation concrète de ce bloc dont je ne pourrais pas me passer ?
    C'est pas très courant mais ça peut être utile pour de l'initialisation spécifique à la classe.

    Par exemple avec JNI (ou JNA) ca permet de charger la librairie native automatiquement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class MaClasse {
        static {
            // chargement de la librairie
        }
     
        public native void methodeNative();
    }

    Sinon j'ai déjà utiliser cela pour initialiser plusieurs variables conjointement, sans avoir à répéter les traitements (qui pourraient être "long").




    Citation Envoyé par Gugelhupf Voir le message
    Peut-être mais pourquoi en faire autant ? ("out.").
    En C# il suffit de faire Console.Write() ou WriteLine()
    Au bout d'un moment ça devient lourd pour les tests.[/code]
    Par curiosité : comment tu écris sur la sortie d'erreur ???
    Sinon on parle d'1 à 3 caractères en plus (selon le cas)...




    Citation Envoyé par Gugelhupf Voir le message
    @adiGuba

    Yield possède un comportement bien particulier. Lorsque qu'une méthode retourne une liste de valeur (ex: List<String> methode(){} ), on n'alloue pas tous les éléments de la liste en mémoire en bloc, mais juste celle d'un élément String qu'on retourne à chaque présence du mot yield.
    Par pur curiosité, je voudrais bien voir un équivalent simple en Java de yield... sans yield.
    yield ne construit pas une liste mais un itérateur.
    L'implémentation de yield en Java reviendrait à ce que le compilateur implémente automatiquement un Iterator/Iterable.
    Pour info c'est comme cela que ca ce passe en C#, cf la dernière partie de ce tuto : http://romainverdier.developpez.com/...urs-en-csharp/

    Donc tout ce que tu peux faire avec un yield tu pourrais la faire avec un Iterator (mais ce sera moins juste pratique à écrire).




    a++

  10. #30
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 740
    Points
    3 740
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Ben une classe anonyme, c'est une classe locale qui n'a pas de nom
    En faite je demandais dans le cas où si on retirait techniquement la possibilité de créer des classes locales... pourrait-t-on toujours créer des classes Anonyme ? Si on ne peut pas : classes Anonymes = sucre syntaxique de classe locale.
    Mais comme je ne sais pas si une classe Anonyme est une feature récente de Java, et que je n'ai pas cherché à décompiler le bytecode d'une classe contenant une classe Anonyme (je ne sais pas si le bytecode décompilé contient une classe locale à la place d'une classe Anonyme), je ne sais pas si on peut qualifier une classe Anonyme de sucre syntaxique pour les classe locales.
    Pour moi une classe locale ça ne sert vraiment pas à grand chose...

    PS: En fait, je parle du cas où si on devait casser le backward compatibilty de Java. D'où le remplacement de nom de méthode comme getRuntime() (singleton) par getInstance() ou getSingleton(), ou la sucre pour println().


    Par curiosité : comment tu écris sur la sortie d'erreur ???
    Question piège : System.err.println(); Je la connais
    Lorsque je veux afficher une erreur j'utilise e.printStackTrace() ou e.getMessage() mais jamais System.err.println();
    Je n'ai jamais vraiment compris la différence entre "out" et "err", si ce n'est que "err" indique explicitement qu'il s'agit d'un message d'erreur...
    Mais toujours est-t-il que lorsqu'on est débutant, qu'on veut afficher tout plein de messages sur la console, c'est plus sympa d'avoir print ou println que System.out.println(), je sais que ça ne joue pas sur grand chose, mais c'est psychologique.

    Bonne soirée,
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  11. #31
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    je n'ai pas cherché à décompiler le bytecode d'une classe contenant une classe Anonyme (je ne sais pas si le bytecode décompilé contient une classe locale à la place d'une classe Anonyme)
    Oui, ca crée bien une classe locale. De memoire, elle a le nom de la classe mere + $N avec N => numéro de la classe anonyme (pour le cas ou il y en aurait plusieurs).

    Citation Envoyé par Gugelhupf Voir le message
    Pour moi une classe locale ça ne sert vraiment pas à grand chose...
    Ca peut etre utile pour ne pas exposer certaines données. Par exemple, c'est sympa pour des classes de stockage de données locales à la classe.

    Citation Envoyé par Gugelhupf Voir le message
    PS: En fait, je parle du cas où si on devait casser le backward compatibilty de Java. D'où le remplacement de nom de méthode comme getRuntime() (singleton) par getInstance() ou getSingleton(), ou la sucre pour println().
    Sur le fond, je pense aussi qu'un getInstance aurait été un choix plus heureux. Mais bon, ca me parait un peu léger comme raison pour casser la compatibilité ascendante.

    Citation Envoyé par Gugelhupf Voir le message
    Je n'ai jamais vraiment compris la différence entre "out" et "err", si ce n'est que "err" indique explicitement qu'il s'agit d'un message d'erreur...
    En fait, ca n'utilise pas la meme sortie. En pratique, dans l'IDE ou dans une console, ca sort tout à la suite (quoique parfois, c'est quand meme entremelé). Mais en fait, System.err sort sur la sortie erreur et System.out sur la sortie standard. On peut par exemple rediriger l'un et l'autre vers 2 fichiers differents. Ou bien jeter l'un et pas l'autre (pour rediriger la sortie standard, c'est 1> et pour la sortie erreur, c'est 2> ).

  12. #32
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    En faite je demandais dans le cas où si on retirait techniquement la possibilité de créer des classes locales... pourrait-t-on toujours créer des classes Anonyme ?
    Les classes locales sont générées avec un nom du style

    package.Principal.Local

    Les classes anonymes sont générées avec un nom du style

    package.Principal.$1
    package.Principal.$2

    etc.

    Pour le reste c'est le même. Difficile de s'en passer tellement ça facilite l'écrire des listeners, observer et autres interfaces de notification. On les verra probablement de moins en moins utilisées au profit des lambdas, mais je ne vois pas l'intérêt de les retirer.



    Pour moi une classe locale ça ne sert vraiment pas à grand chose...
    Ce n'est pas parce que toi tu n'en a jamais eu l'utilité que ce n'est pas utile. Quelques exemples d'utilisation courantes:

    Dans une structure de type liste chainées ou similaire, créer une classe qui représente la structure des noeuds de cette liste. En dehors de la liste chainées, personnes n'a besoin de connaître cette structure.
    Avoir une classe directement liée à la classe englobante, c'est le cas par exemple de la classe Map.Entry, ça n'a pas de sens d'aller la remplacer par une classe MapEntry, qui ne serait de toutes façons pas utilisable sans la Map.

    Créer des structures, nécessaires à l'implémentation interne d'un algorithme spécifique, codé dans une ou deux méthodes, et dont les appelant n'ont aucun besoin de connaître cette structure.
    Mais toujours est-t-il que lorsqu'on est débutant, qu'on veut afficher tout plein de messages sur la console, c'est plus sympa d'avoir print ou println que System.out.println(), je sais que ça ne joue pas sur grand chose, mais c'est psychologique.
    Si t'a vraiment besoin de ça, tu crée un méthode statique println dans une classe à toi et tu fais un import static dessus. Moi quand je débute, j'aimerais pouvoir écrire mon code sans devoir créer un objet et un main dedans. Mais c'est pas possible, et je ne vois pas l'intérêt de changer java pour pouvoir travailler comme un cochon

  13. #33
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    En faite je demandais dans le cas où si on retirait techniquement la possibilité de créer des classes locales... pourrait-t-on toujours créer des classes Anonyme ? Si on ne peut pas : classes Anonymes = sucre syntaxique de classe locale.
    Mais comme je ne sais pas si une classe Anonyme est une feature récente de Java, et que je n'ai pas cherché à décompiler le bytecode d'une classe contenant une classe Anonyme (je ne sais pas si le bytecode décompilé contient une classe locale à la place d'une classe Anonyme), je ne sais pas si on peut qualifier une classe Anonyme de sucre syntaxique pour les classe locales.
    Oui les méthodes anonymes sont du sucres syntaxiques pour des classes locales...
    Et on peut même considérer ces dernières comme du sucres syntaxique pour des classes tout court, puisque le compilateur peut créer des méthodes supplémentaires ou ajouter des paramètres aux constructeurs afin de permettre l'accès aux variables d'instances ou locales.



    Citation Envoyé par Gugelhupf Voir le message
    PS: En fait, je parle du cas où si on devait casser le backward compatibilty de Java. D'où le remplacement de nom de méthode comme getRuntime() (singleton) par getInstance() ou getSingleton(), ou la sucre pour println().
    Il est possible de remplacer getRuntime() par getInstance() sans casser la retro, simplement en dépréciant la méthode...


    Citation Envoyé par Gugelhupf Voir le message
    Question piège : System.err.println(); Je la connais
    Lorsque je veux afficher une erreur j'utilise e.printStackTrace() ou e.getMessage() mais jamais System.err.println();
    Je demandais en C#, puisqu'il y a uniquement Console.WriteLine()...

    Citation Envoyé par Gugelhupf Voir le message
    Je n'ai jamais vraiment compris la différence entre "out" et "err", si ce n'est que "err" indique explicitement qu'il s'agit d'un message d'erreur...
    C'est surtout deux flux différents que tu peux séparer.
    C'est très utile pour séparer les erreurs du reste des messages...


    Citation Envoyé par Gugelhupf Voir le message
    Mais toujours est-t-il que lorsqu'on est débutant, qu'on veut afficher tout plein de messages sur la console, c'est plus sympa d'avoir print ou println que System.out.println(), je sais que ça ne joue pas sur grand chose, mais c'est psychologique.
    Au contraire c'est une coté "magique" qui rajoute de l’ambiguïté.
    Et puis je ne pense pas que ce soit approprié d'ajouter des "trucs" dans le langages juste pour faire plaisir aux débutants...
    Parce que ca risque vite de devenir un fourre-tout incompréhensible ! (un peu comme PHP )

    Pourquoi pourrait-on appeler directement println() et pas exit() par exemple ?
    Pourquoi devrait-on modifier toutes la logique d'appel de méthode juste pour une seul d'entre elle ?
    Il y a des milliers de méthode. Comment déterminer celle qui pourront être appelé directement ou pas ?
    Et justement cela risquerait de troubler les débutants qui ne comprendront pas pourquoi ca marche avec println() et pas avec d'autre méthode !


    Pour moi c'est justement ce qui fait un peu la force de Java : ne pas accepter tête baissé n'importe quelle fonctionnalité simplement parce que "ce serait bien" !
    Car sinon on peut vite se retrouver avec plein de cas particulier dans tous les sens sans aucune cohérence...


    a++

  14. #34
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Ce n'est pas le mécanisme en lui même qui pose problème, mais le fait que les méthodes wait()/notify() soit présente dans Object et donc dans tous les classes...
    Bref plutôt qu'en faire des méthodes d'instances de Object, cela aurait dû être des méthodes static d'une classe du package java.lang...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // Au lieu d'écrire :
    object.wait();
    object.notify();
     
    // On utiliserait :
    Synchronizer.wait(object);
    Synchronizer.notify(object);
    Cela permettrait d'épurer un peu la classe Object...
    Vu que c'est lié au bloc synchronized, je dirais qu'il faut en faire des instructions (mot clé) au même titre ...

    Citation Envoyé par adiGuba Voir le message
    Il me semble que la suppression des primitives est prévu pour Java 10...
    Qu'on est déjà ce qui nous faut dans Java 8, on parlera des futures road map quand il sera temps de la coder.


    Citation Envoyé par adiGuba Voir le message
    +1 pour le yield. Même si ca peut être bien pratique dans certains cas c'est juste du sucre syntaxique.
    Pour le reste les lambdas et surtout les références de méthode permettront d'avoir quelque chose de très proche des delegate du C#.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MyButton extends JButton {
     
        public MyButton(String name) {
            super(name);
            addActionListener(this::myMethod);
        }
     
        private void myMethod(ActionEvent event) {
            // code
        }
    }
    Perso je trouve que c'est même plus puissant car il n'y a pas de type "delegate", mais une simple interface fonctionnelle (avec une seule méthode abstraite), ce qui apporte plein d'avantage :
    • C'est compatible avec plein de code existant (et les interfaces mono-méthodes sont très courantes).
    • On conserve le choix d'utiliser une méthode ou une classe implémentant l'interface (pour des trucs plus complexe).
    • Ces interfaces fonctionnelles n'ont qu'une seule méthode abstraites, mais elles peuvent avoir une API plus complète avec les méthodes par défaut.
    Je n'avais pas vu passer la syntaxe this::myMethod. Je dois dire que je suis pas encore passé à Java 7 alors Java 8 ...

    Citation Envoyé par adiGuba Voir le message
    Ca pourrait être pratique dans certains cas.
    J'utilise GWT et ils ont un compilateur spécifique qui permet d'intégrer du JavaScript dans une classe Java (en le faisant passer pour une méthode native).
    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public native String hostname() /*-{
        // code javascript
        return location.hostname;
    }-*/;
    Ce serait pratique de pouvoir faire des truc comme cela en vrai Java via l'API de Scripting...
    Le problème à traiter c'est le lien avec le code source et la complexité à lire/mettre en forme le code source. Est-ce que finalement définir les méthodes en "native" côté Java et simplifier la "plugabilité" par exemple en indiquant les critères nécessaires ?
    Exemple :
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    @Script(name="Rhino", uri="classpath://hostname.js")
    public native String hostname();
     
    @Script(extension="js")
    public native String hostname();
     
    @Script(mimeType="application/Javascript")
    public native String hostname();

    Citation Envoyé par Gugelhupf Voir le message
    On peut forcer l'emploi du mot-clé "public" alors ?
    Je n'ai pas compris

    Citation Envoyé par Gugelhupf Voir le message
    Lorsque je veux créer une classe X héritant d'une classe X+1 d'une lib qui ne m'appartient pas, je ne sais pas si dans la hiérarchie une classe X+n implémente Serializable, et je ne pense pas forcément à créer une classe X qui est Serializable. Du coup je me retrouve avec une classe implémentant par défaut Serializable sans l'être vraiment. Si C# utilise l'annotation [Serializable] pour ses classes au lieu d'implémenter une interface, c'est qu'il doit y avoir une raison.
    Je savais pas que C# était une référence ^_^
    Plus sérieusement :
    1. Une annotation sur une classe n'empêche pas les classes filles d'y être assujettie. Prends exemple de l'API JUnit, tu peux définir des annotations sur des méthodes/classes. Les classes filles et les "override" méthodes seront également prises en compte comme si elles portaient l'annotation.
    2. Si à un moment dans la hiérarchie on a décidé qu'il était valable que les instances soient sérialisables, c'est parce qu'à ce moment on a souhaité (eu besoin ?) qu'on puisse sérialiser les instances de cette classe. Dans ce cas, les instances des classes filles se doit de l'être aussi.
    3. Le compilateur et les IDE te rappellent rapidement à l'ordre


    Citation Envoyé par Gugelhupf Voir le message
    Donc si je comprends bien, sans classes locales, il ne pourrait pas y avoir de classe Anonyme ?
    On pourrait l'empêcher mais c'est le même sucre syntaxique. Concrètement, les classes locales n'existent pas non plus. A la fin il en resultera une classe avec un nom bizarre et des droits de visibilité particuliers. Pour les classes locales non statiques, il s'agit simplement d'ajouter un attribut du type de la classe encapsulante (enclosing) et de passer l'instance au paramètre de chaque constructeur de la classe encapsulée (enclosed).

    Citation Envoyé par Gugelhupf Voir le message
    Pourrais-tu me montrer une utilisation concrète de ce bloc dont je ne pourrais pas me passer ?
    Tu peux t'en passer en gardant les classes locales. Il existe également un contournement mais il n'est pas isofonctionnel.
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    public class StaticBlock {
      static {
        System.out.println("static initializer");
      }
    }
     
    public class TrickWithInnerClass {
      private static class InnerClass {
        InnerClass() {
          System.out.println("static initializer");
    	}
      }
     
      private static final InnerClass staticInitializer = new InnerClass();
    }
     
    public class TrickWithSynchronizer {
      private static AtomicBoolean staticInitializerFlag = new AtomicBoolean(false);
     
      // To be called on any static method and constructor
      private static final staticInitializer() {
        if (!staticInitializerFlag.getAndSet(true)) {
    	  System.out.println("static initializer");
    	}
      }
    }
    Concernant son utilité, c'est tous les morceaux de code qui doivent être exécuté une et une seule fois. Tu peux prendre le chargement des dll et l'API de Cryptographie en exemple.


    Citation Envoyé par Gugelhupf Voir le message
    Oui ça amuse aussi Oracle (exam certification) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class Sequence {
    Sequence() { System.out.print("c "); }
    { System.out.print("y "); }
    public static void main(String[] args) {
    new Sequence().go();
    }
    void go() { System.out.print("g "); }
    static { System.out.print("x "); }
    }
     
    /*
    What is the result?
    A) c x y g
    B) c g x y 
    C) x c y g
    D) x y c g
    E) y x c g
    F) y c g x
    */
    Source.
    Mais idem que pour le précédent, est-ce vraiment utile ?
    Ca sert si tu as beaucoup de constructeurs et que tu veux pas ajouter un appel de méthode à tous les constructeurs. Sinon je te l'accorde aucun.


    Citation Envoyé par Gugelhupf Voir le message
    Peut-être mais pourquoi en faire autant ? ("out.").
    En C# il suffit de faire Console.Write() ou WriteLine()
    Au bout d'un moment ça devient lourd pour les tests.
    Comme en Java Faut juste remplacer Write/WriteLine par printf.


    Citation Envoyé par Gugelhupf Voir le message
    Je peux dire oui pour tout ce que tu as dis plus haut, mais là non. Le SQL est le langage par excellence pour la fouille de données 2D (et plus de dimensions avec les extensions Microsoft comme MDX pour les cubes, bien que pas standard).
    Impossible de réinventer la roue. Certains prédisent la mort de Java d'ici 20 ans. Pour le SQL ? C'est tout bonnement impossible et ce n'est pas des couches objets comme Hibernate qui pourront faire mieux (PS: Je parle bien sur pour les requêtes de type SELECT).
    SQL est un langage pseudo-normé dont peu de SGBD respecte la norme ... Et désolé R est bien meilleur (plus excellent) pour la fouille de données


    Citation Envoyé par Gugelhupf Voir le message
    Yield possède un comportement bien particulier. Lorsque qu'une méthode retourne une liste de valeur (ex: List<String> methode(){} ), on n'alloue pas tous les éléments de la liste en mémoire en bloc, mais juste celle d'un élément String qu'on retourne à chaque présence du mot yield.
    Par pur curiosité, je voudrais bien voir un équivalent simple en Java de yield... sans yield.
    Les interfaces, c'est pourquoi les closures (et surtout les method références) sont bien plus souples. Tu peux passer plusieurs comportements en paramètre et non pas un seul.
    Par ailleurs, je t'invite à lire Fonction Object Design pattern - Tutoriel sur les foncteurs
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  15. #35
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Nemek Voir le message
    Vu que c'est lié au bloc synchronized, je dirais qu'il faut en faire des instructions (mot clé) au même titre ...
    Ce serait une solution, même si personnellement je ne suis pas favorable à l'ajout de mot-clef lorsqu'une méthode peut suffire...

    Citation Envoyé par Nemek Voir le message
    Je n'avais pas vu passer la syntaxe this::myMethod. Je dois dire que je suis pas encore passé à Java 7 alors Java 8 ...
    C'est la syntaxe des références de méthode.
    Cela permet d'associer une méthode à une interface fonctionnelle (cad avec une seule méthode abstraite) à condition que la signature des deux méthodes correspondent...

    Grosso-modo c'est un raccourci pour une expression lambda qui appellerait cette méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // Avec un lambda :
    addActionListener( (e) -> this.myMethod(e) );
    // Avec une référence de méthode:
    addActionListener( this::myMethod );

    a++

  16. #36
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 740
    Points
    3 740
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Ce n'est pas parce que toi tu n'en a jamais eu l'utilité que ce n'est pas utile. Quelques exemples d'utilisation courantes:

    Dans une structure de type liste chainées ou similaire, créer une classe qui représente la structure des noeuds de cette liste. En dehors de la liste chainées, personnes n'a besoin de connaître cette structure.
    Avoir une classe directement liée à la classe englobante, c'est le cas par exemple de la classe Map.Entry, ça n'a pas de sens d'aller la remplacer par une classe MapEntry, qui ne serait de toutes façons pas utilisable sans la Map.

    Créer des structures, nécessaires à l'implémentation interne d'un algorithme spécifique, codé dans une ou deux méthodes, et dont les appelant n'ont aucun besoin de connaître cette structure.
    Et bien justement, j'ai créé une classe ArbreBinaire générique, dans lequel j'ai créé une classe interne privé static Noeud. Donc pas de classe locale, mais une classe interne (nested class). Et je n'ai rien contre les classes internes contrairement aux classes locales (celles qu'on peut déclarer dans une méthode, un bloc conditionnel, une boucle ! C'est de la folie !).

    Entry est une interface interne public static, pas une classe locale. Ce qui me parait étrange, c'est qu'on ne peut pas créer d'interface locale, mais qu'on peut créer une classe Anonyme à partir d'une interface... bizarre tout ça




    @Nemek
    C'est le cas pour les interfaces "par nature". Ce qui me choque plus c'est l'abscence de mot clé.
    @Gugelhupf
    On peut forcer l'emploi du mot-clé "public" alors ?
    @Nemek
    Je n'ai pas compris :s
    Et bien au lieu de ne mettre aucune visibilité (défaut), on force l'utilisateur à mettre un mot-clé (public/protected/private) pour que le programme compile.
    Ainsi il n'y aura pas "d'absence de mot-clé".
    Mais là encore je ne comprends pas pourquoi il existe une visibilité défaut, c'est juste un piège pour les débutants. Il m'est déjà arrivé d'être coincé pendant plusieurs heures à cause de ce problème. D'où la raison pour laquelle je pense que la visibilité "défaut" actuelle en Java devrait plutôt avoir un comportement "public".



    SQL est un langage pseudo-normé dont peu de SGBD respecte la norme ... Et désolé R est bien meilleur (plus excellent) pour la fouille de données
    J'ai déjà vu des personnes faire du R, c'est un langage orienté maths. R est impératif, contient des blocs conditionnelles et des boucles, donc rien à voir avec le SQL (même s'il est possible de réaliser des conditions et d'avoir de la récursivité en SQL, SQL n'est pas PL/SQL, PL/pgSQL ou Transact-SQL qui sont justes des extensions fournit par les SGBDR).

    Si, le SQL est normé !
    @Wikipedia
    SQL-86, SQL-89, SQL-92, SQL:1999, SQL:2003, SQL:2008, SQL:2011
    La plupart des SGBDR que j'utilise comme PostgreSQL, SQL Server et Oracle respectent ces normes. Jusqu'à maintenant je n'ai eu aucune difficulté à faire fonctionner une requête entre 2 SGBDR différents à partir d'un copier/coller.
    Après oui il y a quelques différences, par exemple SQL Server n'implémente pas des fonctions aussi intuitives que PostgreSQL/Oracle pour TO_CHAR() et TO_DATE() (mais ce n'est pas une fonction standard).
    Prenons par exemple le mot-clé CURRENT_TIMESTAMP qui fait parti du standard, que beaucoup de gens connaissent sous le nom générique de NOW() dans certaines base de données comme MySQL. Et bien même si NOW() n'est pas reconnu dans certains SGBDR que j'ai pu tester, CURRENT_TIMESTAMP l'est




    PS: Merci pour vos exemples.
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  17. #37
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    Ce qui me parait étrange, c'est qu'on ne peut pas créer d'interface locale, mais qu'on peut créer une classe Anonyme à partir d'une interface... bizarre tout ça
    L'intérêt d'une classe locale (anonyme ou pas), c'est qu'elle peut accéder au attributs d'instance de la classe parente et aux variables finales de la méthode.

    Du coup il n'y a aucun intérêt à avoir des interfaces locales car elles ne comportent aucune implémentation.

    Quand aux classes anonymes, même si elle implémente une interface... ca reste une classe qui peut donc bénéficier de ces avantages


    Citation Envoyé par Gugelhupf Voir le message
    Et bien au lieu de ne mettre aucune visibilité (défaut), on force l'utilisateur à mettre un mot-clé (public/protected/private) pour que le programme compile.
    Ainsi il n'y aura pas "d'absence de mot-clé".
    Mais là encore je ne comprends pas pourquoi il existe une visibilité défaut, c'est juste un piège pour les débutants. Il m'est déjà arrivé d'être coincé pendant plusieurs heures à cause de ce problème. D'où la raison pour laquelle je pense que la visibilité "défaut" actuelle en Java devrait plutôt avoir un comportement "public".
    Je suis d'accord que la visibilité "défaut" qui devrait être explicite via un mot clef...
    Par contre je ne suis pas d'accord pour que ce soit du public par défaut. Pour moi les attributs d'une classe devrait être private !

    Comme quoi c'est pas évident de contenter tout le monde lorsqu'on doit concevoir un langage


    a++

  18. #38
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    . Donc pas de classe locale, mais une classe interne (nested class).
    Ha oui, problème de terminologie . Je ne fais jamais la distinction puisque pour moi c'est exactement la même chose. Simplement dans un cas le bloc englobant est une classe, dans un autre, le bloc englobant est une méthode, une loop, etc.


    Mais c'est vrai que la terminologie est différente aussi chez oracle. Ma reflexion sur l'algorithme ayant besoin d'une structure reste vraie, pour autant que l'algo reste limité à une méthode. C'est d'ailleur l'exemple donné par oracle.

  19. #39
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    Et bien justement, j'ai créé une classe ArbreBinaire générique, dans lequel j'ai créé une classe interne privé static Noeud. Donc pas de classe locale, mais une classe interne (nested class). Et je n'ai rien contre les classes internes contrairement aux classes locales (celles qu'on peut déclarer dans une méthode, un bloc conditionnel, une boucle ! C'est de la folie !).
    Ok, méa culpa. Je n'avais pas saisie la nuance. Il s'agit bien d'un sucre syntaxique. Et les classes locales sont bien strictement des pendant des classes anonymes. Les variables finales et l'instance génératrice sont stockées en tant qu'attribut de classe.
    Cependant tu peux très bien t'amuser à faire la même chose manuellement mais ca risque d'être chiant.

    L'avantage de la classe locale c'est que tu peux lui donner un nom et un sens. L'avantage aussi c'est d'avoir la déclaration au plus proche de son utilisation. Après c'est un choix qui se discute mais je pense qu'il est justifiable et utile.

    De toutes façons tu peux faire sans. C'est un peu comme l'histoire de la surcharge des opérateurs en C++.

    Citation Envoyé par Gugelhupf Voir le message
    Et bien au lieu de ne mettre aucune visibilité (défaut), on force l'utilisateur à mettre un mot-clé (public/protected/private) pour que le programme compile.
    Ainsi il n'y aura pas "d'absence de mot-clé".
    Mais là encore je ne comprends pas pourquoi il existe une visibilité défaut, c'est juste un piège pour les débutants. Il m'est déjà arrivé d'être coincé pendant plusieurs heures à cause de ce problème. D'où la raison pour laquelle je pense que la visibilité "défaut" actuelle en Java devrait plutôt avoir un comportement "public".
    Ah ok je pensais que tu disais autre chose.


    Citation Envoyé par Gugelhupf Voir le message
    J'ai déjà vu des personnes faire du R, c'est un langage orienté maths. R est impératif, contient des blocs conditionnelles et des boucles, donc rien à voir avec le SQL (même s'il est possible de réaliser des conditions et d'avoir de la récursivité en SQL, SQL n'est pas PL/SQL, PL/pgSQL ou Transact-SQL qui sont justes des extensions fournit par les SGBDR).
    C'est bien le problème de SQL, parfois t'es obligé de "lire" plusieurs fois la même table. Les optimiseurs sont parfois intelligents et ils ne sont pas plusieurs passent mais généralement ils appliquent bêtement l'algorithme.
    Par ailleurs, les requêtes sont souvent construites de manière séquentielle, je veux tel information, puis tel autre. Au final, j'ai l'impression que le langage est mauvais en tout.
    Je préfère les algos d'appareillage de fichier que l'on trouve dans les batchs COBOL.

    Citation Envoyé par Gugelhupf Voir le message
    Si, le SQL est normé !
    @Wikipedia
    Je sais bien qu'il existe des normes mais elles sont incomplètes (Par exemple, les conversions de type que tu donnes) et non respecté.

    Citation Envoyé par Gugelhupf Voir le message
    La plupart des SGBDR que j'utilise comme PostgreSQL, SQL Server et Oracle respectent ces normes. Jusqu'à maintenant je n'ai eu aucune difficulté à faire fonctionner une requête entre 2 SGBDR différents à partir d'un copier/coller.
    Après oui il y a quelques différences, par exemple SQL Server n'implémente pas des fonctions aussi intuitives que PostgreSQL/Oracle pour TO_CHAR() et TO_DATE() (mais ce n'est pas une fonction standard).
    Prenons par exemple le mot-clé CURRENT_TIMESTAMP qui fait parti du standard, que beaucoup de gens connaissent sous le nom générique de NOW() dans certaines base de données comme MySQL. Et bien même si NOW() n'est pas reconnu dans certains SGBDR que j'ai pu tester, CURRENT_TIMESTAMP l'est
    Je connais bien Oracle, un peu SQL Server et MySQL mais pas du tout PostgreSQL. Mais de ce que j'ai pu voir PostgreSQL ressemble beaucoup à Oracle que ce soit en syntaxe ou en fonctionnalité. Mais pour les autres, ca n'a rien à voir ; dès que l'on touche à quelque chose d'un peu complexe/optimisé c'est même pas la peine ...


    Pour en revenir au sujet, a-t-on des nouvelles de ce nouveau Jigsaw ? Et quel est son objectif par rapport à OSGi (en dehors de la modularisation de la JVM) ?
    Modulariser la JVM pourrait commencer par splitter "rt.jar", créer une unité physique serait déjà un bon début.

    Et quid des "super package", ca ressemble à quoi au final ?
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  20. #40
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    Donc pas de classe locale, mais une classe interne (nested class). Et je n'ai rien contre les classes internes contrairement aux classes locales (celles qu'on peut déclarer dans une méthode, un bloc conditionnel, une boucle ! C'est de la folie !).
    Ah oui, effectivement, comme je n'utilise jamais de classe "locale" (seulement "internes"), je ne faisais pas cette distinction. D'un autre coté, c'est bel et bien ce à quoi une classe anonyme revient. Et celles-ci sont quand meme tres pratiques...

    Concernant la visibilité par défaut, je suis d'accord, je mettrais aussi plutot private par défaut. Et puisqu'on en est à raler sur ce qui n'existe pas, j'aurais aimé une visibilité limitée à la classe et aux sous-classes (contrairement à protected, pas de visibilité aux classes du meme package).

Discussions similaires

  1. Java : Oracle adopte une nouvelle nomenclature pour les mises à jour du JDK
    Par Cedric Chevalier dans le forum Général Java
    Réponses: 8
    Dernier message: 20/05/2013, 19h58
  2. Réponses: 2
    Dernier message: 03/11/2010, 01h38
  3. Nordea lance une nouvelle application iPhone pour ses fonds
    Par Mejdi20 dans le forum Communiqués
    Réponses: 0
    Dernier message: 12/10/2010, 00h27
  4. Réponses: 0
    Dernier message: 03/05/2010, 16h58
  5. Réponses: 0
    Dernier message: 20/04/2010, 12h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo