Java SilverはSE界隈では人気の資格だと聞きます。
特に、将来Javaを使う人、現在Javaを使っている人にとっては、実力を示す資格になると思います。
そんなJava Silverを、C#を専門にやってきた人間が受けるとどうなるか、実践したのでお話しします。
あと、JavaとC#の違いについても書いてみます。
結果
合格でした。
筆者経験
上の記事で書いてあることですが、Javaの経験は若干しかありません。
記事には書かなかったですが、経験は2か月だけです。
C#は5年ぐらいやっています。
勉強期間
…
4日、です。
余裕だと思っていて、でも一応勉強しよう、と思ったのが、4日前でした。
その時点では、半分ぐらいしか解けていない状況でした。
その期間は毎日3時間以上は勉強しています。
教材
定番ですが、これです。
電子書籍です。
宣伝になりますが、本体価格30%オフ、20%クーポン、以前のポイント50倍キャンペーンのポイントを組み合わせて、実質235円(定価:3,456円)で買っています。
勉強終わってからBookOffとかに売るより、はるかに安上がりなので、電子書籍にしました。
問題と解答の行ったり来たりが面倒ですが、しおり機能があるので、慣れてからは紙より楽という…
勉強した部分
勉強部分というより、最初解けなかった分野達です。
性質上、完全初心者の方は置いてけぼりになると思いますが…すみません。
staticインポート
他パッケージのstaticメンバーを、クラス名無しに参照できる機能です。
- static インポート無し
public static void main(string[] args) { system.out.println(Integer.MAX_VALUE); }
- static インポート有り
import java.lang.Integer.MAX_VALUE; public static void main(string[] args) { system.out.println(MAX_VALUE); }
C#だと、6から追加されています。
using static System.Math; static void Main(string[] args) { int max = Max(100, 200); //200が返る }
エントリポイントのルール
C#だと、だいぶルールが緩く、書き方もいろいろあります。
Main() とコマンドライン引数 (C# プログラミング ガイド) | Microsoft Docs
- publicであること
- staticであること
- stringの配列を受け取ること
- 戻り値は返せない(voidであること)
というルールがあります。
なお、Java Silver の問題集では、やたらとmain
のオーバーロードを作りたがりますが、現実ではそんなことは絶対にやらないでください。
数値リテラル
int i = 5_______2;
だと、i == 52
だそうです。
…は?
文字列(コンスタントプール)
C#でもJavaでも、文字列(string型)は参照型に分類されます。
そして、Javaでは、等価を表す==
を使っても、文字列同士だと内容が一緒でもfalse
が返ってくるのですが…
String a = "Pot"; String b = "Pot"; println(a == b);
のように、リテラルで文字列を生成した場合、インスタンスを使い回すという事態が発生します。よって、上記結果はtrue
となります。
これは、Javaの仕様らしく、コンスタントプールというそうです。
…なんというか、メモリ節約にしても微々たるものじゃないか…?
switch文
配列
普通にJavaやC#を使っていて、配列を使うことなんて皆無*2ですが、試験では出るので…
C#では、
int[] arr = new int[3];
のような感じで初期化しますが、Javaだと上記だけでなく
int arr[] = new int[3];
でも初期化できるそうです。*3
初期化ブロック
クラス内で、単に{}
で囲まれた部分は、コンストラクタより前に実行されます。
public class Sample { { //初期化ブロック } public Sample(){ //通常のコンストラクタ } }
使うとしたら、C#のstaticコンストラクタと同等だと思います。*4
継承
継承はextends
、インターフェイス実装はimplementation
です*5が、それはどうでもいいです。
C#では、継承元のメソッドをオーバーライドする場合、override
キーワードの付与が強制されます。
Javaは付けなくても継承されるので、注意が必要です。
オーバーライドは、試験でもいっぱい出るので、よく理解したほうが良いです。
例外処理(try catch finally)
この記事が詳しいです。
試験では、例外処理は必ず出るのですが、問題集には上記の問題が出ていました。
Javaでは、finally句内でreturnすると、おかしな動きをするので、おそらく使用しない方針なのでしょう。
C#では、そこは踏襲しなかったようで、finally句内でreturnを書くと、コンパイルエラーになります。
インポート
Javaのimport
ですが、C#と異なり、クラス名まで指定が要求されます。
それはそれでよいですが、
import my.program.*;
のように書くと、my.program
配下のクラスが全て使えます。
ただし、パッケージ内のパッケージは参照できないので、
import my.program.*; import my.program.core.*;
のように、さらに下にパッケージがある場合は、こうやってインポートします。
この辺りは、C#のusingと一緒です。
インターフェイス
ここは、似てるようで異なる部分です。表にしましょう。
特徴 | Java | C# |
---|---|---|
フィールド宣言 | 可(強制的に定数となる) | 不可 |
プロパティ | - | 可 |
メンバーのアクセス修飾子 | 付加できる(無視される) | 不可 |
デフォルト定義 | 可 | - |
public interface Tester { public void test(); }
のように書けますが、publicは無視されます。何を付けようが強制的にpublicです。
ラムダ式
ラムダ式は、要するに名前のないメソッドです。
強い静的型付けのおかげで、なかなか強力な型推論が働き、ソースが短く書けるので、なかなか重宝します。
ただし、このラムダ式、C#とJavaでは挙動が異なる部分もあるので、注意です。
public void Print(){ int value = 100; Action act = () => Console.WriteLine(value * value); value = 50; act(); //2500と表示 }
C#では、ラムダ式内部で、外部定義した変数を見ていても、特に問題ありません。
public void Print(){ int value = 100; Function act = () -> system.out.println(value * value); value = 50; act(); //コンパイルエラー! }
Javaでは、ラムダ式内部で、外部定義した変数を見る場合、その変数は定数扱いでなければならないそうです。
まとめ
今後、初めてJavaを勉強していく!という方にはあまり意味のない記事かと思います。すみません。
JavaとC#はよく似ていますが、やっぱりかなり違いがあるな、という印象を記事にしてみました。
C#は、Javaの後発言語*6である分、分かりづらい部分、問題が起こりやすい部分には、かなり対処したというのがよく分かりました。
…それでも、null非許容型を用意しなかったところとか、惜しいところはあると思いますが。
個人的には、C#の、新しいものを取り入れてく部分とかは好きです。
いろんな言語を知っていると、新しい発見とかあって面白いので、サブ言語みたいなもの作ってもいいかもしれないですね。
どうでもいいこと
Java Silverを じゃばしる と勝手に呼んでいます。