Hey james thanks yet again for a lucid explanation. Ya I have been using pen and paper for drawing links between ref vars and created objects.

Great thanks james! On the topic of objects and reference variable I had one more doubt.

public class Swanky {
    Swanky s;
    public static void main(String r[]) {
        Swanky s1 = new Swanky();
        s1.s = new Swanky();
        go(s1.s);
        Swanky s2 = go(s1);
    }

    static Swanky go(Swanky s) {
        Swanky gs = new Swanky();
        gs.s = s;
        return gs;
    }

In this extremely confusing code for me, the first invocation go(s1.s) once enters the go() creates a set of ref var and objects namely two ref var s, gs and one object. That is fine. Now what I want to udnerstand is when second go(s1) call happens and it enters the method, this time it creates separate s and gs ref var or re-uses the first time created one?

import java.util.*;
public class Elway {
    public static void main(String r[]) {
        ArrayList[] ls = new ArrayList[3];
        for(int i=0; i<3; i++) {
            ls[i] = new ArrayList();
            ls[i].add("a" + i);  }

        Object o = ls;
        do3(ls);
        for(int i=0; i<3; i++)
            //insert code here
        }

    static Object do3(ArrayList[] a) {
        for(int i=0; i<3; i++) a[i].add("e");
        return a;
    }
}

The code above compiles fine with:
a. System.out.println(((Object[])o)[i] + " ")
b. System.out.println(((ArrayList[])o)[i] + " ")
but not with
c. System.out.println(o[i] + " ")

What is the reason? When we assigned ls to o, didn't Object o become an array?

Thanks again james!

Why I asked that question was because I noticed with super wild card, that whatever is on the RHS(right hand side) of super keyword is only accepted or it's sub class.

For e.g.

NavigableSet<? super Object> set = new TreeSet<Object>();
            set.add(new Object()); 
            set.add(new String("Hello"));

is accepting both Object and String following my assumption of anything on RHS of super or it's subclass.

So going back to my very first post,

List<? super Integer> list = new ArrayList<Integer>();
            for (Integer element : list) { 
                System.out.println(element); 

this should accept and Integer object and hence in the for loop when list varible is assigned to another Integer wrraper itself, why complains of incompatible types ?? :( :(

Likewise for

NavigableSet<?> set = new TreeSet<Object>();
            set.add(new Object());

Saying same error as one on previous post.

Ok so in general the first line of both case which is instantiation says what compatible elements can be added into the list? if that's the case why is this code below wrong:

NavigableSet<? super String> set = new TreeSet<String>();
set.add(new Object());

Compiler says cannot find symbol: method add(java.lang.Object)
Isn't <? super String> should allow addition of Object since it is a superclass of String?

List<? extends Integer> list = new ArrayList<Integer>();
            for (Integer element : list) { 
                System.out.println(element);

List<? super Integer> list = new ArrayList<Integer>();
            for (Integer element : list) { 
                System.out.println(element); 

For the first three lines as Case 1 using extends it compiles fine. But for Case 2 of next three lines, it says incompatible types. Found Object, required Integer. My confusion is ? extends Integer being anything that is an Integer or sub of it works.

But why in Case 2 where ? super Integer means anything that is an Integer or a superclass of Integer doesn't work when it's elements ar being given to an Integer element in the for loop??

Thanks guys!

StringBuffer sb = new StringBuffer(new String("Hello")); //Case 1
StringBuffer sb1; //Case 2
String s = new String("Hello"); // Case 2
sb1=s; //Case 2
StringBuffer sb3; //Case 3
sb3 = new String("Hello");//Case 3

Case 1 compiles fine and outputs Hello but Case 2 and Case 3 gives compiler error saying incompatible types. Why is it so?

Hey no problem James :) you have helped me on tons of occasions so thank you :)

James I found an answer on some random site. But I could not understand it. Here it is.

The parameterized type for Hose is E, and you have defined E to extend Hose, however you have not defined for which type it should extend Hose.

Hence, for the class E, the method E getE(); is different depending on for which type Hose is extended. As it currently stands you have extended it for its raw type, without a parametrized type.

This is hard to explain I notice... consider this, instead of your current class definition of Hose, you use:
public class Hose <E extends Hose<E>> {

This will make your code compile. What I tried saying above is that for the class definition I just provided, the method:
public E getE() {

.. will indeed return a class of the same type, both from class Hose and from class E. If you do not define the parameterized type for E in the class definition for Hose, as I have done above, then there is no telling what the method would return when used from the class E.

P.S. Above is the entire answer I have copied from that site. Nothing I have written on my own.
The class is renamed to Hose here instead of GenericDemo but it's that very same program in question. Could you explain in layman terms what is being explained above please?

Particularly what is meant in the very first line **"however you have ...

Hahaha :) Well it's Kathy Sierra and Bert Bates. These guys are the main duo who make questions for the Oracle's Java Programmer Certification Test. So it is from their mock test book.

public class GenericDemo<E extends GenericDemo> {
    E innerE;

    public E doStuff(E e, GenericDemo<E> e2) {
        //insert code here
        }

    public E getE() { return innerE; }
}

The options are:

  1. return e
  2. return e2.getE()
  3. return e2
  4. return e.getE()

Option (1) and (2) compile fine. Option (3) and (4) give compile error.

  1. Precisely, for e2 says, incompatible types. Found: GenericDemo<E>. Required: E.
    My doubts is that, for e2, isn't E that is required, part of GenericDemo<E> which is e2's type ?

  2. For return e.getE() says, incompatible types. Found: GenericDemo. Required: E. Here I'm first confused as to how the return type is determined for a method invocation. getE() according to method signature returns E. But invoking it through e.getE() returns GenericDemo?? How is that happening? And even variable e is of the type E? So where is GenericDemo coming from when compiler says found: GenericDemo?

  3. And how is option(2) e2.getE() returning E that is actually compiled fine?

I hope I'm able to convey my doubts correctly.

Thanks guys.

Does it jump to random position? May be some hardware key on your keyboard is pressed? Check.

Something like intermediate level tutorials link please?

I won't need to ask anyone else james thanks :) actually that typo between A.java and A.class was confusing me. I have understood the topic :)

P.S. I would be very grateful if you could provide me some link on good and concise eclipse tutorial. Not something like Eclipse for dummies. I am little past that stage :)
Thanks.

And also it has to compile and execute B.java. And for that it needs A.class not A.java(It would need A.java to generate the classfile but it's already there). So why does it have to look for A.java?

Thanks James, I also wanted to ask although it might sound silly to you. Is there a difference at all between root dir and current dir?

foo
|-test
    |-xcom
        |-A.class
        |-B.java

And two files:

package xcom;
public class A{}

package xcom
public class B extends A{}

Given above directory structure where root dir is foo. Class B extends A.

Question is:
Which allows B.java to compile?
The answer is: Set the current dir to test then invoke javac -cp . xcom/B.java

My doubt is why the option below won't work?

  1. Set the current dir to xcom then invoke javac -cp . B.java ? Isn't this looking for A.class in xcom because of the (.) ?
  2. By setting test as current dir, and using (.) isn't it searching for A.class only in test dir and not xcom?
  3. Also it says in solution, because A.class is in xcom package, it will not find A.class if invoked from xcom dir. Why is that? Won't the (.) make it work?

Thanks guys :)

I have one more doubt regardig Anonymous Class.

    class Sample { 
        void go() {
            Bar b = new Bar();
            b.met(new Foo() {
                public void foof() { System.out.println("foofy");}
                }); 
            } //end go()
        } //end Sample class

    interface Foo { void foof(); }

    class Bar { void met(Foo f) { } }

My doubt is that how can you instantiate an interface (inside the met() arg) when that is strictly not allowed? Or is it an exception case for Anonymous class?

Oh god! Such silly mistakes will cost me big in the SCJP exam!!! :( Thanks for pointing it out!

public class IC1 {
    private int x = 3;
    static int y=4;

    class Inner {
        public void inmet() { System.out.println(x + " " + y);} }

    public void do() {
        Inner i = new Inner();
        i.inmet(); }

    public static void main(String r[]) {
        IC1 ic = new IC1();
        ic.do();
    }
}

Errors

Seems like a pretty straight forward program where in my knowledge I have followed all rules of Inner Class. Checked all {} and ; also. What could be the reason for the errors?

Got it :)

class Account { Long accNum, pwd}
public class Banker {
    public static void main(String r[]) {
        new Banker().go();
        // do more stuff }

    void go() {
        Account a1 = new Account();
        a1.accNum = new Long("1024");
        Account a2 = a1;
        Account a3 = a2;
        a3.pwd = a1.accNum.longValue();
        a2.pwd = 4455L;
        }
    }

It says in solution when line 5, "//do more stuff" is reached, four objects are eligible for GC.

Three I know is Banker(), Account() and Long("1024"). My doubt is which is the fourth one?
It says in solution that "Account object has two Long objects associated with it". So my guess is 4455L is considered an object, making it the fourth object eligible for GC? If so afterall, my second doubt is isn't it a primitive value?

Hmmm thanks! Read up on type erasure after you explained :) After understanding the concept even I agree with your opinion.

Understandable that at compile time doesn't know what will be passed to met() since it's parameter is a non gen List but at Runtime why isn't ClassCastException thrown for incompatible elements stored in List l1 which allows ONLY Animal or Dog?

import java.util.*;
class Animal{Animal() {System.out.println("Animal constructor");}}
class Dog extends Animal{Dog() {System.out.println("Dog constructor");}}

public class GenericDemo7 {
    public static void main(String r[]) {
        List<Animal> l1 = new ArrayList<Animal>(); 
        l1.add(new Dog());
        l1.add(new Animal());
        met(l1);
        System.out.println(l1); }

    public static void met(List l2) {
        l2.add(new Integer(3)); 
        l2.add(3.14); 
        l2.add(new Animal());
        System.out.println(l2); }}

How do I interpret this now? The var l1 is instatantiated to be type safe so after l1 is passed to a non generic method, does the type get erased and allows addition of Integer and double?