References and variable passing. Explain the output of this simple java program?
<p><strong>Quick summary of what I need help with:</strong></p>

<ul>
<li>What's an immutable class?</li>
<li>With Java's String class, why can you not 'point' one String variable at another (using C terminology) like you can with other classes? For example, <code>String x=(String)y;</code> copies y's value over to x. Why?
<ul>
<li>For example, with my own class ('Test'), <code>Test x=(Test)y;</code> does properly 'point' x at y.
<br></li>
</ul></li>
<li>Does String's behaviour here have anything to do with its immutability?</li>
</ul>

<hr>

<p>I have this Java program... can someone explain what's going on with the references?</p>

<pre><code>public class Main {

    public static void foo(String a){
        a="2";
    }

    public static void main(String[] args) {
        String x="1";
        foo(x);
        System.out.println("x="+x);

    }

}
</code></pre>

<p>Output:</p>

<pre><code>x=1
</code></pre>

<p>Expected Output:</p>

<pre><code>x=2
</code></pre>

<p>What's going on? I thought that whatever I do to <code>a</code> within <code>foo</code> would also affect <code>x</code>, as <code>a</code> is just an alias for <code>x</code> - no?</p>

<p>A similar issue here:</p>

<pre><code>public class Main {
    public static void main(String[] args) {
        String x=new String("1");
        String y=new String("2");
        y=x;
        x="3";
        System.out.println("x="+x);
        System.out.println("y="+y);
    }

}
</code></pre>

<p>Output:</p>

<pre><code>x=3
y=1
</code></pre>

<p>Expected Output:</p>

<pre><code>x=3
y=3
</code></pre>

<p>Can someone explain this?</p>

<hr>

<p>Edit:</p>

<p>Why do these examples produce the expected results and my above examples with String didn't?</p>

<p>1:</p>

<pre><code>public class Main {

    private static class Test{
        public String val;
        public Test(String set){val=set;}
        public Test(){}
    }
    public static void foo(Test a){
        a.val="2";
    }
    public static void main(String[] args) {
        Test x=new Test("1");
        foo(x);
        System.out.println("x="+x.val);
    }

}
</code></pre>

<p>Output (and expected output):</p>

<pre><code>x=2
</code></pre>

<p>2:</p>

<pre><code>public class Main {

    private static class Test{
        public String val;
        public Test(String set){val=set;}
        public Test(){}
    }
    public static void main(String[] args) {
        Test x=new Test("1");
        Test y=new Test("2");
        x=y;
        x.val="3";
        System.out.println("x="+x.val);
        System.out.println("y="+y.val);
    }

}
</code></pre>

<p>Output (and Expected Output):</p>

<pre><code>x=3
y=3
</code></pre>
