SE(たぶん)の雑感記

一応SEやっている筆者の思ったことを書き連ねます。会計学もやってたので、両方を生かした記事を書きたいと考えています。 でもテーマが定まってない感がすごい。

C#erが、じゃばしる(Java 8 Silver:Java SE 8 Programmer Ⅰ)に合格したので、C#と比較する

Java SilverはSE界隈では人気の資格だと聞きます。
特に、将来Javaを使う人、現在Javaを使っている人にとっては、実力を示す資格になると思います。

そんなJava Silverを、C#を専門にやってきた人間が受けるとどうなるか、実践したのでお話しします。
あと、JavaC#の違いについても書いてみます。

結果

f:id:hiroronn:20170930143436p:plain

合格でした。

筆者経験

hiroronn.hatenablog.jp

上の記事で書いてあることですが、Javaの経験は若干しかありません。
記事には書かなかったですが、経験は2か月だけです。

C#は5年ぐらいやっています。

勉強期間

4日、です。

余裕だと思っていて、でも一応勉強しよう、と思ったのが、4日前でした。
その時点では、半分ぐらいしか解けていない状況でした。

その期間は毎日3時間以上は勉強しています。

教材

定番ですが、これです。

honto.jp

電子書籍です。
宣伝になりますが、本体価格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

Javaは、C#と比較するとガチガチに決まっていて、

  • 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文

C#と異なり、breakは強制されません。*1

配列

普通にJavaC#を使っていて、配列を使うことなんて皆無*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)

この記事が詳しいです。

qiita.com

試験では、例外処理は必ず出るのですが、問題集には上記の問題が出ていました。

Javaでは、finally句内でreturnすると、おかしな動きをするので、おそらく使用しない方針なのでしょう。

C#では、そこは踏襲しなかったようで、finally句内でreturnを書くと、コンパイルエラーになります。

インポート

Javaimportですが、C#と異なり、クラス名まで指定が要求されます。
それはそれでよいですが、

import my.program.*;

のように書くと、my.program配下のクラスが全て使えます。

ただし、パッケージ内のパッケージは参照できないので、

import my.program.*;
import my.program.core.*;

のように、さらに下にパッケージがある場合は、こうやってインポートします。

この辺りは、C#のusingと一緒です。

インターフェイス

ここは、似てるようで異なる部分です。表にしましょう。

特徴 Java C#
フィールド宣言 可(強制的に定数となる) 不可
プロパティ -
メンバーのアクセス修飾子 付加できる(無視される) 不可
デフォルト定義 -

Javaインターフェイスでは、

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を勉強していく!という方にはあまり意味のない記事かと思います。すみません。
JavaC#はよく似ていますが、やっぱりかなり違いがあるな、という印象を記事にしてみました。

C#は、Javaの後発言語*6である分、分かりづらい部分、問題が起こりやすい部分には、かなり対処したというのがよく分かりました。
…それでも、null非許容型を用意しなかったところとか、惜しいところはあると思いますが。

個人的には、C#の、新しいものを取り入れてく部分とかは好きです。

いろんな言語を知っていると、新しい発見とかあって面白いので、サブ言語みたいなもの作ってもいいかもしれないですね。

どうでもいいこと

Java Silverを じゃばしる と勝手に呼んでいます。


*1:C#では、空じゃないcaseから別のcase間にbreakが無いと、コンパイルエラーになる

*2:一応、C#ではループ効率が最も良いとのことから、ループ前にシーケンスを配列変換する場合はある。しかし、自分で配列生成して、一つ一つ要素を当てはめる機会は殆ど無い

*3:他の言語から流入してくる開発者のため!とのこと

*4:C#のstaticコンストラクタは、最初にクラスが参照された時に実行される処理を指す

*5:C#は、クラス名 : 継承クラス,実装インターフェイス

*6:Javaを大いに参考にしたと思われる