Javaの勉強をはじめた

Javaを使うことになったので勉強をはじめたんだけど、文字列の比較でひっかかった。
最初、何気なく文字列を==で比較してみるとTrueとなって欲しいところがFalseとなる。
調べてみるとJavaでは比較のときは、equalsメソッドを使うのが定石のようだ。

import java.util.*;

class Sample {
    public static void main(String[] args){
        String s1 = new String("Hello");
        String s2 = new String("Hello");

        // Trueを表示
        if(s1.equals(s2))
            System.out.println("True");
        else
            System.out.println("False");
        // Falseを表示
        if(s1 == s2)
            System.out.println("True");
        else
            System.out.println("False");
        // Trueを表示
        if(s1.equals("Hello"))
            System.out.println("True");
        else
            System.out.println("False");
        // Falseを表示
        if(s1 == "Hello")
            System.out.println("True");
        else
            System.out.println("False");
    }
}

文字列の場合、Stringクラスをインスタンス化したオブジェクトのため、変数に代入されている値は、メモリ上の別の場所に存在する文字列オブジェクトを参照しているリファレンスです。

http://www.atmarkit.co.jp/fjava/onepoint/java/jv14.html

リファレンスというのがよくわかんないけど、ポインタみたいなものかな?
と考えると、==はポインタ同士を比較して、equalsメソッドはポインタの参照先同士を比較するといった感じだろうか。Cで書くとこんな感じの違いか?そのままgccコンパイルするとs1とs2は同じアドレスを指すので-fwritable-stringsオプションを付ける。

char *s1 = "A";
char *s2 = "A";
// Falseが表示。ポインタ同士を比較。
if(s1 == s2)
    printf("True\n");
else
    printf("False\n");
// Trueが表示。参照先同士を比較。
if(*s1 == *s2)
    printf("True\n");
else
    printf("False\n");