Q:

Why does this generic java method accept two objects of different type?

This method shall take two objects of the same type and return one of those objects by random:
public static <T> T random(T o1, T o2)
{
   return Math.random() < 0.5 ? o1 : o2;
}

Now, why does the compiler accept two parameters with distinctive types?
random("string1", new Integer(10)); // Compiles without errors

EDIT:
Now that I know that both parameters are getting implicitly upcasted, I wonder why the compiler does complain when calling the following method:    
public static <T> List<T> randomList(List<T> l1, List<T> l2) {
        return Math.random() < 0.5 ? l1 : l2;
    }

Call:
randomList(new ArrayList<String>(), new ArrayList<Integer>()); // Does not Compile

If those ArrayList Parameters are also getting upcasted to Object, why does it give me an error this time?

A:

T is inferred to be Object, and both arguments are getting implicitly upcast.
Thus the code is equivalent to:
Main.<Object>random((Object)"string1", (Object)new Integer(10));

What may be even more surprising is that the following compiles:
random("string1", 10);

The second argument is getting auto-boxed into an Integer, and then both arguments are getting upcast to Object.

A:

T is inferred to be the a common super type of String and Integer, which is
Object & Serializable & Comparable<? extends Object & Serializable & Comparable<? extends ... ...

well, nobody needs to care about that.
You can add a little more constraints on the parameter types
public static <T1,T2 extends T1> T1 random(T1 o1, T2 o2)

In your list example, you need wildcards to get the similar effect
public static <T> List<? extends T> randomList(
                                    List<? extends T> l1, List<? extends T> l2)

A:

Know that I know that both parameters are getting implicitly upcasted,
  I wonder why the compiler does complain when calling the following
  method:

Because even when A is a subtype of B, List<A> is not a subtype of List<B> if A and B are different.

