cannot use MockDaoInterface literal (type MockDaoInterface) as type s3.DaoInterface in assignment: MockDaoInterface does not implement s3.DaoInterface [duplicate] - unit-testing

There are already several Q&As on this "X does not implement Y (... method has a pointer receiver)" thing, but to me, they seems to be talking about different things, and not applying to my specific case.
So, instead of making the question very specific, I'm making it broad and abstract -- Seems like there are several different cases that can make this error happen, can someone summary it up please?
I.e., how to avoid the problem, and if it occurs, what are the possibilities? Thx.

This compile-time error arises when you try to assign or pass (or convert) a concrete type to an interface type; and the type itself does not implement the interface, only a pointer to the type.
Short summary: An assignment to a variable of interface type is valid if the value being assigned implements the interface it is assigned to. It implements it if its method set is a superset of the interface. The method set of pointer types includes methods with both pointer and non-pointer receiver. The method set of non-pointer types only includes methods with non-pointer receiver.
Let's see an example:
type Stringer interface {
String() string
}
type MyType struct {
value string
}
func (m *MyType) String() string { return m.value }
The Stringer interface type has one method only: String(). Any value that is stored in an interface value Stringer must have this method. We also created a MyType, and we created a method MyType.String() with pointer receiver. This means the String() method is in the method set of the *MyType type, but not in that of MyType.
When we attempt to assign a value of MyType to a variable of type Stringer, we get the error in question:
m := MyType{value: "something"}
var s Stringer
s = m // cannot use m (type MyType) as type Stringer in assignment:
// MyType does not implement Stringer (String method has pointer receiver)
But everything is ok if we try to assign a value of type *MyType to Stringer:
s = &m
fmt.Println(s)
And we get the expected outcome (try it on the Go Playground):
something
So the requirements to get this compile-time error:
A value of non-pointer concrete type being assigned (or passed or converted)
An interface type being assigned to (or passed to, or converted to)
The concrete type has the required method of the interface, but with a pointer receiver
Possibilities to resolve the issue:
A pointer to the value must be used, whose method set will include the method with the pointer receiver
Or the receiver type must be changed to non-pointer, so the method set of the non-pointer concrete type will also contain the method (and thus satisfy the interface). This may or may not be viable, as if the method has to modify the value, a non-pointer receiver is not an option.
Structs and embedding
When using structs and embedding, often it's not "you" that implement an interface (provide a method implementation), but a type you embed in your struct. Like in this example:
type MyType2 struct {
MyType
}
m := MyType{value: "something"}
m2 := MyType2{MyType: m}
var s Stringer
s = m2 // Compile-time error again
Again, compile-time error, because the method set of MyType2 does not contain the String() method of the embedded MyType, only the method set of *MyType2, so the following works (try it on the Go Playground):
var s Stringer
s = &m2
We can also make it work, if we embed *MyType and using only a non-pointer MyType2 (try it on the Go Playground):
type MyType2 struct {
*MyType
}
m := MyType{value: "something"}
m2 := MyType2{MyType: &m}
var s Stringer
s = m2
Also, whatever we embed (either MyType or *MyType), if we use a pointer *MyType2, it will always work (try it on the Go Playground):
type MyType2 struct {
*MyType
}
m := MyType{value: "something"}
m2 := MyType2{MyType: &m}
var s Stringer
s = &m2
Relevant section from the spec (from section Struct types):
Given a struct type S and a type named T, promoted methods are included in the method set of the struct as follows:
If S contains an anonymous field T, the method sets of S and *S both include promoted methods with receiver T. The method set of *S also includes promoted methods with receiver *T.
If S contains an anonymous field *T, the method sets of S and *S both include promoted methods with receiver T or *T.
So in other words: if we embed a non-pointer type, the method set of the non-pointer embedder only gets the methods with non-pointer receivers (from the embedded type).
If we embed a pointer type, the method set of the non-pointer embedder gets methods with both pointer and non-pointer receivers (from the embedded type).
If we use a pointer value to the embedder, regardless of whether the embedded type is pointer or not, the method set of the pointer to the embedder always gets methods with both the pointer and non-pointer receivers (from the embedded type).
Note:
There is a very similar case, namely when you have an interface value which wraps a value of MyType, and you try to type assert another interface value from it, Stringer. In this case the assertion will not hold for the reasons described above, but we get a slightly different runtime-error:
m := MyType{value: "something"}
var i interface{} = m
fmt.Println(i.(Stringer))
Runtime panic (try it on the Go Playground):
panic: interface conversion: main.MyType is not main.Stringer:
missing method String
Attempting to convert instead of type assert, we get the compile-time error we're talking about:
m := MyType{value: "something"}
fmt.Println(Stringer(m))

To keep it short and simple, let say you have a Loader interface and a WebLoader that implements this interface.
package main
import "fmt"
// Loader defines a content loader
type Loader interface {
load(src string) string
}
// WebLoader is a web content loader
type WebLoader struct{}
// load loads the content of a page
func (w *WebLoader) load(src string) string {
return fmt.Sprintf("I loaded this page %s", src)
}
func main() {
webLoader := WebLoader{}
loadContent(webLoader)
}
func loadContent(loader Loader) {
loader.load("google.com")
}
The above code will give you this compile time error
./main.go:20:13: cannot use webLoader (type WebLoader) as type Loader
in argument to loadContent:
WebLoader does not implement Loader (Load method has pointer receiver)
To fix it you only need to change webLoader := WebLoader{} to following:
webLoader := &WebLoader{}
Why this will fix the issue? Because you defined this function func (w *WebLoader) Load to accept a pointer receiver. For more explanation please read #icza and #karora answers

Another case when I have seen this kind of thing happening is if I want to create an interface where some methods will modify an internal value and others will not.
type GetterSetter interface {
GetVal() int
SetVal(x int) int
}
Something that then implements this interface could be like:
type MyTypeA struct {
a int
}
func (m MyTypeA) GetVal() int {
return a
}
func (m *MyTypeA) SetVal(newVal int) int {
int oldVal = m.a
m.a = newVal
return oldVal
}
So the implementing type will likely have some methods which are pointer receivers and some which are not and since I have quite a variety of these various things that are GetterSetters I'd like to check in my tests that they are all doing the expected.
If I were to do something like this:
myTypeInstance := MyType{ 7 }
... maybe some code doing other stuff ...
var f interface{} = myTypeInstance
_, ok := f.(GetterSetter)
if !ok {
t.Fail()
}
Then I won't get the aforementioned "X does not implement Y (Z method has pointer receiver)" error (since it is a compile-time error) but I will have a bad day chasing down exactly why my test is failing...
Instead I have to make sure I do the type check using a pointer, such as:
var f interface{} = new(&MyTypeA)
...
Or:
myTypeInstance := MyType{ 7 }
var f interface{} = &myTypeInstance
...
Then all is happy with the tests!
But wait! In my code, perhaps I have methods which accept a GetterSetter somewhere:
func SomeStuff(g GetterSetter, x int) int {
if x > 10 {
return g.GetVal() + 1
}
return g.GetVal()
}
If I call these methods from inside another type method, this will generate the error:
func (m MyTypeA) OtherThing(x int) {
SomeStuff(m, x)
}
Either of the following calls will work:
func (m *MyTypeA) OtherThing(x int) {
SomeStuff(m, x)
}
func (m MyTypeA) OtherThing(x int) {
SomeStuff(&m, x)
}

Extend from above answers (Thanks for all of your answers)
I think it would be more instinctive to show all the methods of pointer / non pointer struct.
Here is the playground code.
https://play.golang.org/p/jkYrqF4KyIf
To summarize all the example.
Pointer struct type would include all non pointer / pointer receiver methods
Non pointer struct type would only include non pointer receiver methods.
For embedded struct
non pointer outer struct + non pointer embedded struct => only non pointer receiver methods.
non pointer outer struct + pointer embedded struct / pointer outer struct + non pointer embedded struct / pointer outer struct + pointer embedded struct => all embedded methods

Related

Is it possible to parameterize a generic with a type that is itself generic? [duplicate]

Is it possible to do something like this in Rust?
trait Foo<T> {}
struct A;
struct B;
struct Bar<T: Foo> {
a: T<A>,
b: T<B>
}
I know I could just use two parameters for Bar, but I think there has to be a better way to do this.
I want to implement a Graph structure. As I can't just bind the nodes and edges to their parents lifetime, I want to have something like Rc. However, sometimes one may need a Graph with access from multiple threads. So I'd have to have both an implementation with Rc and Arc.
That's what Foo is good for: I implement Foo for both Rc and Arc (Foo would require Deref) and I use a parameter T bound to Foo. That's how I wanted to have one struct for single thread and multi thread usage.
⇒ This is currently impossible to express in Rust's type system ☹
Fortunately, it will be possible in the future thanks to "Generic Associated Types" as proposed in this RFC. You can track the status of implementation and stabilization in the corresponding tracking issue.
The important term here is "HKT" (higher kinded types). It's a feature of a type system which is not yet implemented in Rust. Haskell offers HKTs. In the C++ world HKTs are known as "template templates". The generic associated types mentioned above are also a form of HKTs.
But what are HKTs, really?
Let's start slowly: what is a simple type as we know it? Let's list some types: i32, bool, String. These are all types... you can have a value (variable) of these types. What about Vec<i32>? It's also a simple type! You can have a variable of type Vec<i32>, no problem!
We want to group these types together; we call this categorisation a "kind of a type". If we want to talk in a very abstract way (about types of types) we choose other words, kind in this case. There is even a notation for kinds of types. For our simple types from above, we say: the kind of those types is
*
Yes, just a star, very easy. The notation makes more sense later!
Let's search for types that are of a different kind than our simple types. Mutex<HashMap<Vec<i32>, String>>? Nope, it's fairly complex maybe, but it's still of kind * and we still can have a variable of that type.
What about Vec? Yes, we omitted the angle-brackets. Yes, this is indeed another kind of type! Can we have a variable of type Vec? No! A vector of what?!
This kind is donated as:
* -> *
This just says: give me a normal type (*) and I will return a normal type! Give a normal type i32 to this thing (Vec) and it will return a normal type Vec<i32>! It's also called a type constructor, because it is used to construct types. We can even go further:
* -> * -> *
This is a bit strange, because it has to do with currying and reads odd for a non-Haskell programmer. But it means: give me two types and I will return a type. Let's think about an example... Result! The Result type constructor will return a concrete type Result<A, B> after you provided two concrete types A and B.
The term higher kinded types just refers to all kinds of types which are not *, which are type constructors.
In your example
When you write struct Bar<T: Foo> you want T to be of the kind * -> *, meaning: you can give one type to T and receive a simple type. But as I said, this is not yet expressible in Rust. To use a similar syntax, one might imagine that this could work in the future:
// This does NOT WORK!
struct Bar<for<U> T> where T<U>: Foo {
a: T<A>,
b: T<B>,
}
The for<> syntax is borrowed from "higher-ranked trait bounds" (HRTB), which can be used today for abstracting over lifetimes (most commonly used with closures).
Links
In case you want to read more about this topic, here are some links:
Niko Matsakis' great series of blog posts discussing one possible solution (associated type constructors) to the HKT problem
The RFC proposing generic associated types (just a less scary name for "associated type constructors")
HRTB explanation
Bonus: the solution to your problem in case associated type constructors will be implemented (I think, as there is no way to test)!
We have to take a detour in our implementation since the RFC wouldn't allow to pass Rc as a type parameter directly. It doesn't introduce HKTs directly, so to speak. But as Niko argues in his blog post, we can have the same flexibility and power as HKTs with associated type constructors by using so called "family traits".
/// This trait will be implemented for marker types, which serve as
/// kind of a proxy to get the real type.
trait RefCountedFamily {
/// An associated type constructor. `Ptr` is a type constructor, because
/// it is generic over another type (kind * -> *).
type Ptr<T>;
}
struct RcFamily;
impl RefCountedFamily for RcFamily {
/// In this implementation we say that the type constructor to construct
/// the pointer type is `Rc`.
type Ptr<T> = Rc<T>;
}
struct ArcFamily;
impl RefCountedFamily for ArcFamily {
type Ptr<T> = Arc<T>;
}
struct Graph<P: RefCountedFamily> {
// Here we use the type constructor to build our types
nodes: P::Ptr<Node>,
edges: P::Ptr<Edge>,
}
// Using the type is a bit awkward though:
type MultiThreadedGraph = Graph<ArcFamily>;
For more information, you should really read Niko's blog posts. Difficult topics explained well enough, that even I can understand them more or less!
EDIT: I just noticed that Niko actually used the Arc/Rc example in his blog post! I totally forgot that and thought of the code above myself... but maybe my subconscious still remembered, as I choose a few names exactly as Niko did. Anyway, here is his (probably way better) take on the issue.
In a way Rust does have what looks a lot like HKT (see Lukas's answer for a good description of what they are), though with some arguably awkward syntax.
First, you need to define the interface for the pointer type you want, which can be done using a generic trait. For example:
trait SharedPointer<T>: Clone {
fn new(v: T) -> Self;
// more, eg: fn get(&self) -> &T;
}
Plus a generic trait which defines an associated type which is the type you really want, which must implement your interface:
trait Param<T> {
type Pointer: SharedPointer<T>;
}
Next, we implement that interface for the types we're interested in:
impl<T> SharedPointer<T> for Rc<T> {
fn new(v: T) -> Self {
Rc::new(v)
}
}
impl<T> SharedPointer<T> for Arc<T> {
fn new(v: T) -> Self {
Arc::new(v)
}
}
And define some dummy types which implement the Param trait above. This is the key part; we can have one type (RcParam) which implements Param<T> for any T, including being able to supply a type, which means we're simulating a higher-kinded type.
struct RcParam;
struct ArcParam;
impl<T> Param<T> for RcParam {
type Pointer = Rc<T>;
}
impl<T> Param<T> for ArcParam {
type Pointer = Arc<T>;
}
And finally we can use it:
struct A;
struct B;
struct Foo<P: Param<A> + Param<B>> {
a: <P as Param<A>>::Pointer,
b: <P as Param<B>>::Pointer,
}
impl<P: Param<A> + Param<B>> Foo<P> {
fn new(a: A, b: B) -> Foo<P> {
Foo {
a: <P as Param<A>>::Pointer::new(a),
b: <P as Param<B>>::Pointer::new(b),
}
}
}
fn main() {
// Look ma, we're using a generic smart pointer type!
let foo = Foo::<RcParam>::new(A, B);
let afoo = Foo::<ArcParam>::new(A, B);
}
Playground

Is intersection casting possible in Kotlin?

I have a method in Java like so:
public <T extends A & B> methodName(T arg, ...)
where A is a class and B is an interface.
In my kotlin class, I have another variable of type C, and I wish to achieve the following:
if (variable is A && variable is B) {
methodName(variable, ...)
} else {
// do something else
}
Is it possible to properly cast variable so that it may be used as an argument without errors?
Currently, the variable has a setter method, so smart casting isn't
available. However, I have also tested it with a local val and the
value is inferred to have type Any which doesn't help.
Kotlin does not support intersection types. This causes variable to be smart cast to Any, because that is the common ancestor of A and B.
However, Kotlin does support generic type constraints. You can use this to constrain a type parameter to one or more types. This can be used on both methods and classes. This is the syntax for functions (the equivalent of your methodName in Kotlin):
fun <T> methodName(arg: T)
where T : A,
T : B {
....
}
You can use this to get around your problem by creating a class which extends both A and B, and then delegates the implementation of these types to your object. Like this:
class AandB<T>(val t: T) : A by t, B by t
where T : A,
T : B
You can now call methodName by changing your if-test to check if it is a AandB<*>:
if (variable is AandB<*>) {
methodName(variable, ...)
}
You do need to wrap variable in a AandB somewhere though. I don't think you can do it if you don't have the type information for variable available anywhere.
Note: The AandB class does not implement hashCode, equals or toString. You could implement them to delegate to t's implementation.
Note 2: This only works if A and B are interfaces. You can not delegate to a class.
As #marstran points out, the when clause is how you specify multiple bounds. Here's a link to the documentation about upper-bounds. It's worth mentioning that you cannot have multiple bounds if one of your bounds is a generic type parameter.
You mentioned that you tried testing with smart-casting:
However, I have also tested it with a local val and the value is inferred to have type Any which doesn't help.
This is not the case for the current version of Kotlin (v1.4). You do not need to create an AandB class as you can use a val or local (captured) var to smart-cast to an intersection.
Here's an example (and runnable version):
interface I1 { fun one() = println("one") }
interface I2 { fun two() = println("two") }
class Both: I1, I2
val variable: Any = Both() // Starting with type 'Any'
if (variable is I1 && variable is I2) {
// Type is now '(I1 & I2)' Smart-cast from Any
variable.one()
variable.two()
}
Here's a link to more discussion and runnable example of Kotlin intersection types as of v1.4

Is there a decltype equivalent in Swift?

In C++11 and latter, it is possible to use a compile time function like syntax named decltype() to reuse declaration type of a variable to declare another one without rewriting the type signature. Is there any equivalent syntactic tool in Swift?
C++ Example:
class SomeClass {
public:
SomeVeryLongTypeName* my_prop;
}
void foo() {
SomeClass my_var = SomeClass();
// Below code is a variable declaration, not a function call
declytype(my_var.my_prop) some_prop = nullptr;
// Below is same as above
SomeVeryLongTypeName* some_prop = nullptr;
}
There is, as far as I know, no direct equivalent syntactic tool readily available in Swift.
For something slightly similar you could, however, make use of generics to gain access to (at compile time) a metatype (grammar: metatype-type → type­.­Type), whereafter you can use an initializer expression to construct an instance of the concrete type (of the metatype).
protocol Initializable {
init()
}
typealias SomeVeryLongTypeName = Int
extension SomeVeryLongTypeName : Initializable {}
class SomeClass {
let my_prop : SomeVeryLongTypeName
required init() { my_prop = 1 }
}
func declmetatype<T: Initializable>(_: T) -> T.Type {
return T.self
}
func foo() {
let my_var = SomeClass()
let some_prop = declmetatype(my_var.my_prop).init()
some_prop = my_var.my_prop + 1
}
In foo() above, some_prop is of type SomeVeryLongTypeName (which, here, is simply Int), which due to Swift's static typing is naturally known at compile time.
Note, however, that in Swift we cannot use this technique to only declare types, but must also instantiate them. Moreover, there's no concept of "default initializers" in Swift (as compared to default CTOR:s in C++), hence the need to constrain the generic typeholder in declmetatype(...) to a protocol of our own, where we provide a blueprint to some initializer we'd like to use in a "default sense" from the metatype.
We may visit the Language Reference - Types - Metatypes for additional details on metatypes, particularly:
Use an initializer expression to construct an instance of a type
from that type’s metatype value. For class instances, the initializer
that’s called must be marked with the required keyword or the entire
class marked with the final keyword.
Where I've emphasized the available use of metatypes to construct instances of types (as shown above), which does not, however, cover using metatypes to only declare types.

c++ dynamic return type

I'm not sure if this is a thing (to be honest I want to say that it is not), but I was wondering if there is a way to write a c++ function so that it can choose which type of object to return.
For example, I have a base class (A) that has 3 child classes (Aa, Ab, Ac). In a factory(F) class I have a std::map<UINT, A*> that holds a number of the child classes based on a UINT id. My goal is to write a function that can build and return the correct object when I pass in an id value.
I'll probably end up returning pointers and cloning the data that they point to, but I was just curious as to whether or not the aforementioned was actually possible.
Thanks!
C++ being statically typed, the return type of a function must be known at compile time. From here arises the question:
do I know the expected return type statically on each call site of F (== it only depends on constant expression values)
or does it depend on some runtime variable.
For case #1, a function template for F would be a good approach.
But in your case, it seems you are facing #2 (because you want to return a type depending on ID that we can assume is not a constant expression).
Because of the static typing, if you are to write a function (assuming you do not overload it, because it seems your input parameters are always the same), it will have a single and well-defined return type. Basically, you do not have a syntax to say that your factory F will return either an Aa Ab or Ac (and that is a very good thing, with regard to static typing and all the compiler verifications it enables ; )
C++ solution: Type erasure
With that being said, you have a few approaches to type erasure, that will allow you to return an instance of a variant type hidden behind a common single type.
The obvious one is the pointer-to-derived to pointer-to-base conversion. It is particularly usefull if you plan to use the returned object mainly through its A interface (i.e., you will call the virtual functions defined on A).
A* F(ID aId)
This A* could point to any type deriving from A. From here, you could call every function defined on A public interface on the returned pointer. Of course, if you wanted to call an operation that is only available on a subclass, you would need to know what is the exact type on call site,and then cast the pointer to a pointer-to-derived before being able to call the operation.
A possible alternative, if you'd rather avoid dynamic memory, could be boost::variant. At the cost of having to explicitly list all the possible types the function could return.
boost::variant<Aa, Ab, Ac> F(ID aId);
You can take a look at the tutorial for a quick introduction to the syntax and features.
Sure, something like this:
class MyMapClass
{
public:
template< class ExactType > ExactType * getValue(UINT key)
{
return dynamic_cast<ExactType*>(_myMap.at(key));
}
BaseType * at(UINT key)
{
return _myMap.at(key);
}
private:
std::map<UINT, BaseType*> _myMap;
}
However, since you are storing the pointers to base types, you can as well return them as is, and rely on the caller to make a specific cast, if that goes well with your application's architecture.
Unfortunately, you can not do it fully automatically. Sooner or later you will have to determine the exact class that hides behind the base class pointer, and make a cast. With the template solution it is done "sooner":
MyDerivedType * value = myMapClassInstance.getValue<MyDerivedType>(1);
If you prefer to return the base pointer, it is done "later":
BaseType * value = myMapClassInstance.at(1);
MyDerivedType * exactValue = dynamic_cast<MyDerivedType*>(value);

Difference between List<?> and List<T> . [duplicate]

What are the differences between List, List<?>, List<T>, List<E>, and List<Object>?
1. List
List: is a raw type, therefore not typesafe. It will only generate a runtime error when the casting is bad. We want a compile time error when the cast is bad. Not recommended to use.
2. List<?>
List<?> is an unbounded wildcard. But I'm not sure what it's for? I can print a List<?> without issue:
public static void test(List<?> list){
System.out.println(list); // Works
}
Why can't I add items to a List<?>?
public static void test(List<?> list){
list.add(new Long(2)); // Error
list.add("2"); // Error
System.out.println(list);
}
3. List<T>
public static void test(List<T> list){ // T cannot be resolved
System.out.println(list);
}
I don't understand this syntax. I saw something like this, and it works:
public <T> T[] toArray(T[] a){
return a;
}
Sometimes, I see <T>, or <E>, or <U>, <T,E>. Are they all the same or do they represent something different?
4. List<Object>
This gives the error "The method test(List<Object>) is not applicable for the argument List<String>":
public static void test(List<Object> list){
System.out.println(list);
}
If I try this then I got "Cannot cast from List<String> to List<Object>":
test((List<Object>) names);
I am confused. String is a subclass of Object, so why isn't List<String> a subclass of List<Object>?
1) Correct
2) You can think of that one as "read only" list, where you don't care about the type of the items.Could e.g. be used by a method that is returning the length of the list.
3) T, E and U are the same, but people tend to use e.g. T for type, E for Element, V for value and K for key. The method that compiles says that it took an array of a certain type, and returns an array of the same type.
4) You can't mix oranges and apples. You would be able to add an Object to your String list if you could pass a string list to a method that expects object lists. (And not all objects are strings)
For the last part:
Although String is a subset of Object, but List<String> is not inherited from List<Object>.
The notation List<?> means "a list of something (but I'm not saying what)". Since the code in test works for any kind of object in the list, this works as a formal method parameter.
Using a type parameter (like in your point 3), requires that the type parameter be declared. The Java syntax for that is to put <T> in front of the function. This is exactly analogous to declaring formal parameter names to a method before using the names in the method body.
Regarding List<Object> not accepting a List<String>, that makes sense because a String is not Object; it is a subclass of Object. The fix is to declare public static void test(List<? extends Object> set) .... But then the extends Object is redundant, because every class directly or indirectly extends Object.
The reason you cannot cast List<String> to List<Object> is that it would allow you to violate the constraints of the List<String>.
Think about the following scenario: If I have a List<String>, it is supposed to only contain objects of type String. (Which is a final class)
If I can cast that to a List<Object>, then that allows me to add Object to that list, thus violating the original contract of List<String>.
Thus, in general, if class C inherits from class P, you cannot say that GenericType<C> also inherits from GenericType<P>.
N.B. I already commented on this in a previous answer but wanted to expand on it.
I would advise reading Java puzzlers. It explains inheritance, generics, abstractions, and wildcards in declarations quite well.
http://www.javapuzzlers.com/
Let us talk about them in the context of Java history ;
List:
List means it can include any Object. List was in the release before Java 5.0; Java 5.0 introduced List, for backward compatibility.
List list=new ArrayList();
list.add(anyObject);
List<?>:
? means unknown Object not any Object; the wildcard ? introduction is for solving the problem built by Generic Type; see wildcards;
but this also causes another problem:
Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error
List< T> List< E>
Means generic Declaration at the premise of none T or E type in your project Lib.
List< Object> means generic parameterization.
In your third point, "T" cannot be resolved because its not declared, usually when you declare a generic class you can use "T" as the name of the bound type parameter, many online examples including oracle's tutorials use "T" as the name of the type parameter, say for example, you declare a class like:
public class FooHandler<T>
{
public void operateOnFoo(T foo) { /*some foo handling code here*/}
}
you are saying that FooHandler's operateOnFoo method expects a variable of type "T" which is declared on the class declaration itself, with this in mind, you can later add another method like
public void operateOnFoos(List<T> foos)
in all the cases either T, E or U there all identifiers of the type parameter, you can even have more than one type parameter which uses the syntax
public class MyClass<Atype,AnotherType> {}
in your forth ponint although efectively Sting is a sub type of Object, in generics classes there is no such relation, List<String> is not a sub type of List<Object> they are two diferent types from the compiler point of view, this is best explained in this blog entry
Theory
String[] can be cast to Object[]
but
List<String> cannot be cast to List<Object>.
Practice
For lists it is more subtle than that, because at compile time the type of a List parameter passed to a method is not checked. The method definition might as well say List<?> - from the compiler's point of view it is equivalent. This is why the OP's example #2 gives runtime errors not compile errors.
If you handle a List<Object> parameter passed to a method carefully so you don't force a type check on any element of the list, then you can have your method defined using List<Object> but in fact accept a List<String> parameter from the calling code.
A. So this code will not give compile or runtime errors and will actually (and maybe surprisingly?) work:
public static void main(String[] args) {
List argsList = new ArrayList<String>();
argsList.addAll(Arrays.asList(args));
test(argsList); // The object passed here is a List<String>
}
public static void test(List<Object> set) {
List<Object> params = new ArrayList<>(); // This is a List<Object>
params.addAll(set); // Each String in set can be added to List<Object>
params.add(new Long(2)); // A Long can be added to List<Object>
System.out.println(params);
}
B. This code will give a runtime error:
public static void main(String[] args) {
List argsList = new ArrayList<String>();
argsList.addAll(Arrays.asList(args));
test1(argsList);
test2(argsList);
}
public static void test1(List<Object> set) {
List<Object> params = set; // Surprise! Runtime error
}
public static void test2(List<Object> set) {
set.add(new Long(2)); // Also a runtime error
}
C. This code will give a runtime error (java.lang.ArrayStoreException: java.util.Collections$UnmodifiableRandomAccessList Object[]):
public static void main(String[] args) {
test(args);
}
public static void test(Object[] set) {
Object[] params = set; // This is OK even at runtime
params[0] = new Long(2); // Surprise! Runtime error
}
In B, the parameter set is not a typed List at compile time: the compiler sees it as List<?>. There is a runtime error because at runtime, set becomes the actual object passed from main(), and that is a List<String>. A List<String> cannot be cast to List<Object>.
In C, the parameter set requires an Object[]. There is no compile error and no runtime error when it is called with a String[] object as the parameter. That's because String[] casts to Object[]. But the actual object received by test() remains a String[], it didn't change. So the params object also becomes a String[]. And element 0 of a String[] cannot be assigned to a Long!
(Hopefully I have everything right here, if my reasoning is wrong I'm sure the community will tell me. UPDATED: I have updated the code in example A so that it actually compiles, while still showing the point made.)
Problem 2 is OK, because " System.out.println(set);" means "System.out.println(set.toString());" set is an instance of List, so complier will call List.toString();
public static void test(List<?> set){
set.add(new Long(2)); //--> Error
set.add("2"); //--> Error
System.out.println(set);
}
Element ? will not promise Long and String, so complier will not accept Long and String Object
public static void test(List<String> set){
set.add(new Long(2)); //--> Error
set.add("2"); //--> Work
System.out.println(set);
}
Element String promise it a String, so complier will accept String Object
Problem 3: these symbols are same, but you can give them differet specification. For example:
public <T extends Integer,E extends String> void p(T t, E e) {}
Problem 4: Collection does not allow type parameter covariance. But array does allow covariance.
You're right: String is a subset of Object. Since String is more "precise" than Object, you should cast it to use it as an argument for System.out.println().