Développeurs C # apprenant Java, quelles sont les principales différences que l'on peut ignorer [fermé]

87

Pour les développeurs c # qui cherchent à apprendre Java, existe-t-il de grandes différences sous-jacentes entre les deux langages à signaler?

Peut-être que certaines personnes peuvent supposer que les choses sont les mêmes, mais il y a certains aspects de l'importation qui ne devraient pas être négligés? (ou vous pouvez vraiment foutre en l'air!)

Peut-être en termes de constructions POO, de fonctionnement de GC, de références, de déploiement, etc.

mrblah
la source

Réponses:

122

Quelques échappées au sommet de ma tête:

  • Java n'a pas de types de valeur personnalisés (structs), alors ne vous embêtez pas à les rechercher
  • Les énumérations Java sont très différentes de l'approche des «nombres nommés» de C #; ils sont plus OO. Ils peuvent être utilisés à bon escient, si vous faites attention.
  • byte est signé en Java (malheureusement)
  • En C #, les initialiseurs de variable d'instance s'exécutent avant le constructeur de classe de base; en Java, ils s'exécutent après (c'est-à-dire juste avant le corps du constructeur dans la classe "this")
  • En C #, les méthodes sont scellées par défaut. En Java, ils sont virtuels par défaut.
  • Le modificateur d'accès par défaut en C # est toujours "l'accès le plus restrictif disponible dans le contexte actuel"; en Java, c'est un accès "package". (Cela vaut la peine de lire sur les modificateurs d'accès particuliers en Java.)
  • Les types imbriqués en Java et C # fonctionnent quelque peu différemment; en particulier, ils ont des restrictions d'accès différentes, et à moins que vous ne déclariez le type imbriqué comme étant, staticil aura une référence implicite à une instance de la classe contenant.
Jon Skeet
la source
5
+1 Ceci est une excellente liste pour les débutants.
Jim Schubert
3
@Jon Skeet: +1, Et vous manqueriez probablement Lambda et LINQ jusqu'à Java 7?
Kb.
1
"En C #, les initialiseurs de variable d'instance s'exécutent avant le constructeur de classe de base; en Java, ils s'exécutent après lui (c'est-à-dire juste avant le corps du constructeur dans" cette "classe)" - Eeer, pourriez-vous élaborer ceci? Je ne sais pas vraiment ce que vous dites :)
cwap
7
@cwap: En C #, l'ordre d'exécution est "initialiseurs de variable d'instance, constructeur de classe de base, corps de constructeur". En Java, c'est "constructeur de superclasse, initialiseurs de variable d'instance, corps du constructeur". (Les initialiseurs de variable d'instance sont ce que vous obtenez lorsque vous affectez une valeur à une variable d'instance au point de déclaration.)
Jon Skeet
1
@cwap: Oui, c'est ce que je veux dire - ce dernier est un initialiseur d' objet .
Jon Skeet
17

Je suis surpris que personne n'ait mentionné des propriétés, quelque chose d'assez fondamental en C # mais absent en Java. C # 3 et les versions ultérieures ont également implémenté automatiquement des propriétés. En Java, vous devez utiliser des méthodes de type GetX / SetX.

Une autre différence évidente est l'absence d'expressions LINQ et lambda en C # 3 en Java.

Il y a quelques autres choses simples mais utiles qui manquent à Java comme les chaînes verbatim (@ ""), la surcharge d'opérateurs, les itérateurs utilisant yield et le pré-processeur sont également absents de Java.

L'un de mes favoris personnels en C # est que les noms d'espaces de noms n'ont pas à suivre la structure de répertoires physique. J'aime vraiment cette flexibilité.

Softveda
la source
10

Il y a beaucoup de différences, mais celles-ci me viennent à l'esprit:

  • Absence de surcharge d'opérateurs en Java. Regardez votre instance: Equals (instance2) versus instance == instance2 (en particulier w / strings).
  • Habituez-vous à ce que les interfaces ne soient PAS préfixées par un I. Vous voyez souvent des espaces de noms ou des classes suffixés avec Impl à la place.
  • Le verrouillage vérifié deux fois ne fonctionne pas en raison du modèle de mémoire Java.
  • Vous pouvez importer des méthodes statiques sans les préfixer avec le nom de la classe, ce qui est très utile dans certains cas (DSL).
  • Les instructions Switch en Java ne nécessitent pas de valeur par défaut et vous ne pouvez pas utiliser de chaînes comme étiquettes de cas (IIRC).
  • Les génériques Java vous mettront en colère. Les génériques Java n'existent pas au moment de l'exécution (au moins dans la version 1.5), ils sont une astuce du compilateur, ce qui pose des problèmes si vous voulez faire une réflexion sur les types génériques.
Sneal
la source
4
La dernière fois que j'ai vérifié, les chaînes n'ont PAS surchargé ==, et je n'ai pas non plus entendu parler de son ajout pour Java 7. Cependant, ils surchargent + pour la concaténation de chaînes.
Michael Madsen
3
Oui, comparer des chaînes avec == est un piège très courant pour les débutants. .equalsest ce que vous devez utiliser.
Michael Myers
De plus, je ne comprends pas le commentaire sur les méthodes statiques. À peu près tous les langages n'autorisent pas les méthodes statiques ou l'équivalent?
Michael Myers
J'ai presque voté pour cela, mais je ne suis pas d'accord sur les génériques. J'aime l'effacement de type.
finnw
2
«Les instructions de commutation en Java ne nécessitent pas de valeur par défaut» - pas plus que C #.
RenniePet
8

.NET a réifié les génériques; Java a effacé les génériques.

La différence est la suivante: si vous avez un ArrayList<String>objet, en .NET, vous pouvez dire (à l'exécution) que l'objet est de type ArrayList<String>, alors qu'en Java, à l'exécution, l'objet est de type ArrayList; la Stringpièce est perdue. Si vous mettez des non- Stringobjets dans le ArrayList, le système ne peut pas appliquer cela, et vous ne le saurez qu'après avoir essayé d'extraire l'élément, et la distribution échoue.

Chris Jester-Young
la source
1
... même si cela vaut la peine d'ajouter que vous ne pouvez pas mettre des non- Stringobjets dans cette liste sans faire un cast non vérifié, quelque part , et le compilateur vous avertira correctement à ce stade que le compilateur ne peut plus vérifier les limites génériques. Tant que votre liste est toujours stockée dans une variable de List<String>, les tentatives pour y insérer un objet non String ne seront pas compilées.
Andrzej Doyle
« objets non-String dans le ArrayList, le système ne peut pas appliquer cette »: Notez que le système ne l' appliquer à la compilation. Vous pouvez cependant contourner cela en castant (ou en n'utilisant pas de génériques); alors la vérification d'exécution l'attrapera, mais seulement lors de l'extraction.
sleske
1
@Andrzej, @sleske: Je ne parle que du runtime. Supposons que vous obteniez l'objet par réflexion et invoquiez sa addméthode (encore une fois, par réflexion). Le système rejettera-t-il un non- Stringobjet tout de suite, ou seulement lors de la diffusion du résultat de get?
Chris Jester-Young
@sleske: Mais IIRC vous avez seulement besoin d'un cast implicite pour contourner la vérification de type.
Niki le
@Judah: J'ai annulé votre changement (oui, un an après le fait), car vous ne pouvez pas avoir d'objets de type List. Vous pouvez avoir des objets de types descendant de List, comme ArrayListet LinkedList. (Il est important de les utiliser Listau lieu de ArrayListles faire circuler, mais cela ne change pas le fait que vous ne pouvez pas dire new List().)
Chris Jester-Young
6

Une chose qui me manque dans C # de Java est la gestion forcée des exceptions vérifiées. En C #, il est bien trop courant que l'on ignore les exceptions qu'une méthode peut lancer et que vous êtes à la merci de la documentation ou des tests pour les découvrir. Ce n'est pas le cas en Java avec des exceptions vérifiées.

Sean
la source
1
FWIW, cela a été pris en compte dans le développement de C # et la justification de leur exclusion est réelle. Considérez artima.com/intv/handcuffs.html . Ce n'est pas que les concepteurs soient philosophiquement opposés aux exceptions vérifiées - ils attendent plutôt une meilleure technique qui offre des avantages similaires sans tous les inconvénients poilus.
Greg D
Oui, oui, un sujet très controversé ...
sleske
2
J'aime le fait que C # n'ait pas vérifié les exceptions, mais c'était le premier article à même souligner la différence, donc +1.
Nick
5

Java a une autoboxing pour les primitives plutôt que pour les types valeur, donc bien qu'il s'agisse d' System.Int32[]un tableau de valeurs en C #, il Integer[]s'agit d'un tableau de références à des Integerobjets et, en tant que tel, ne convient pas aux calculs de performances plus élevées.

Pete Kirkham
la source
1
Pete: c'est un excellent point, et que je n'ai jamais connu ou du moins jamais envisagé (étant développeur C # et nouveau sur Java).
Jim Schubert
4

Pas de délégués ni d'événements - vous devez utiliser des interfaces. Heureusement, vous pouvez créer des classes et des implémentations d'interface en ligne, donc ce n'est pas si grave

thecoop
la source
3
"n'est pas si grave". Droite. Parce que x => x.Foovs new Bar() { public void M(SomeType x) { return x.Foo; } }- qui se soucie que le code soit 10 fois plus court?
Kirk Woll
2

La fonctionnalité de date / calendrier intégrée à Java est horrible par rapport à System.DateTime. Il y a beaucoup d'informations à ce sujet ici: Quel est le problème avec l'API Java Date & Time?

Certains d'entre eux peuvent être récupérés pour un développeur C #:

  • La classe Java Date est modifiable, ce qui peut rendre les dates de retour et de passage dangereuses.
  • La plupart des constructeurs java.util.Date sont obsolètes. Instancier simplement une date est assez détaillé.
  • Je n'ai jamais eu la classe java.util.Date pour bien interagir avec les services Web. Dans la plupart des cas, les dates de chaque côté ont été sauvagement transformées en une autre date et heure.

De plus, Java n'a pas toutes les mêmes fonctionnalités que le GAC et les assemblys fortement nommés. Jar Hell est le terme pour désigner ce qui peut mal tourner lors de la liaison / du référencement de bibliothèques externes.

En ce qui concerne le packaging / déploiement:

  • il peut être difficile de regrouper des applications Web au format EAR / WAR qui s’installent et s’exécutent sur plusieurs serveurs d’applications différents (Glassfish, Websphere, etc.).
  • le déploiement de votre application Java en tant que service Windows demande beaucoup plus d'efforts qu'en C #. La plupart des recommandations que j'ai reçues à ce sujet impliquaient une bibliothèque tierce non gratuite
  • la configuration de l'application n'est pas aussi simple que l'inclusion d'un fichier app.config dans votre projet. Il existe une classe java.util.Properties, mais elle n'est pas aussi robuste et trouver le bon endroit pour déposer votre fichier .properties peut être déroutant
intoOrbit
la source
1

Il n'y a pas de délégués en Java. Par conséquent, outre tous les avantages que les délégués apportent à la table, les événements fonctionnent également différemment. Au lieu de simplement connecter une méthode, vous devez implémenter une interface et l'attacher à la place.

BGratuit
la source
1

Une chose qui saute aux yeux car c'est sur ma liste d'interview est qu'il n'y a pas de "nouveau" mot-clé analogique en Java pour le masquage de méthode et donc aucun avertissement du compilateur "vous devriez en mettre nouveau ici". Une méthode accidentelle qui se cache lorsque vous avez l'intention de remplacer entraîne des bogues.

(modifier par exemple) Exemple, B dérive de A (en utilisant la syntaxe C #, Java se comporte de la même manière que j'ai vérifié la dernière fois mais n'émet pas d'avertissement du compilateur). Le toto de A est-il appelé ou le toto de B? (A est appelé, surprenant probablement le développeur qui a implémenté B).

class A 
{
public void foo() {code}
}

class B:A
{
public void foo() {code}
}    

void SomeMethod()
{
A a = new B(); // variable's type is declared as A, but assigned to an object of B.
a.foo();
}
Jim L
la source
2
Comment cachez-vous accidentellement une méthode d'instance en Java? ils sont soit définitifs - donc pas de remplacement ou newméthode à cacher intentionnellement - ou non finaux donc remplacés plutôt que cachés.
Pete Kirkham le
Exemple ajouté. Je ne l'ai pas testé en Java depuis un moment, mais la question de l'interview provenait à l'origine du groupe Java de ma société précédente. En C #, l'avertissement du compilateur signifie généralement que les gens changent le nom. J'admets que c'est un cas assez étrange, mais OP semblait demander des choses qui seraient potentiellement difficiles à trouver des problèmes lors du changement de langue.
Jim L
1
La différence ici est qu'en Java toutes les méthodes sont virtuelles (donc en Java, ce sera B.foo () qui sera appelée car Java effectue toujours une répartition dynamique des méthodes), alors qu'en C # les méthodes ne sont pas virtuelles par défaut (et A.foo () serait appelé). De nombreux vérificateurs de style de codage pour Java vous indiqueront que B doit utiliser l'annotation @Override.
William Billingsley
1

Java n'a pas LINQ et la documentation est un enfer. Les interfaces utilisateur en Java sont difficiles à développer, vous perdez toutes les bonnes choses que Microsoft nous a données (WPF, WCF, etc ...) mais vous devenez des "API" difficiles à utiliser et à peine documentées.

Turing terminé
la source
0

Le seul problème que j'ai rencontré jusqu'à présent lorsque je travaille avec Java provenant de C # est que les exceptions et les erreurs sont différentes.

Par exemple, vous ne pouvez pas détecter une erreur de mémoire insuffisante en utilisant catch (Exception e).

Voir ce qui suit pour plus de détails:

pourquoi-java-lang-outofmemoryerror-java-heap-space-not-catch

Chris Persichetti
la source
Il est intentionnellement conçu de cette façon pour décourager le programmeur d'application de l'attraper
finlandais
Oui, je suis sûr que c'était le cas, mais venant du côté C #, où tout ce dont vous avez à vous soucier est d'attraper des exceptions, m'a jeté pour une boucle :)
Chris Persichetti
0

Cela fait si longtemps que je ne suis pas en Java, mais les choses que j'ai remarquées dès le départ dans le développement d'applications étaient le modèle d'événement C #, le glisser-déposer C # vs l'utilisation des gestionnaires de mise en page dans Swing (si vous faites du développement d'applications) et la gestion des exceptions avec Java en s'assurant que vous interceptez une exception et que C # n'est pas requis.

Jason Too Cool Webs
la source
0

En réponse à votre question très directe dans votre titre:

«Les développeurs C # apprenant Java, quelles sont les plus grandes différences que l'on peut ignorer?

R: Le fait que Java soit considérablement plus lent sous Windows.


la source
4
Je lance OpenSuSE 64bit et Windows 7 64bit, et Eclipse IDE est ("semble") plus rapide sous Windows. Votre réponse est-elle basée sur une observation personnelle ou sur des repères réels?
Jim Schubert
0

La différence la plus déchirante pour moi lorsque je passe à java, c'est la déclaration de chaîne.

en C # string(la plupart du temps) en JavaString

C'est assez simple, mais croyez-moi, cela vous fait perdre tellement de temps quand vous avez l'habitude de sne pas le faire S!

iChaib
la source