Generic without type as method parameter - can't resolve it's field type
Clash Royale CLAN TAG#URR8PPP
up vote
9
down vote
favorite
Let's consider a class:
public class Foo<T>
public List<String> list = new ArrayList<>();
that I'm passing as a parameter to a method.
I have a problem understanding why here the type String
isn't resolved:
public void test(Foo t)
t.list.get(0).contains("test");
and the t.list
is treated as List<Object>
while here everything works just fine:
public void test(Foo<?> t)
t.list.get(0).contains("test");
and t.list
is List<String>
.
java generics
add a comment |Â
up vote
9
down vote
favorite
Let's consider a class:
public class Foo<T>
public List<String> list = new ArrayList<>();
that I'm passing as a parameter to a method.
I have a problem understanding why here the type String
isn't resolved:
public void test(Foo t)
t.list.get(0).contains("test");
and the t.list
is treated as List<Object>
while here everything works just fine:
public void test(Foo<?> t)
t.list.get(0).contains("test");
and t.list
is List<String>
.
java generics
Murat has answered your question, but you are aware that the<T>
inFoo<T>
is redundant, right?
– Michael
2 hours ago
@Michael yes, it was just for the purpose of giving an example where theT
isn't used for the actual field type.
– Jakubs
2 hours ago
1
Possible duplicate of Compiler error on Java generic interface with a List<> method
– Oleksandr
1 hour ago
@Oleksandr in fact both questions are about the same problem but approach it from a different angle. Facing my problem and not knowing the solution I would be unable to understand the underlying reason behind both.
– Jakubs
1 min ago
add a comment |Â
up vote
9
down vote
favorite
up vote
9
down vote
favorite
Let's consider a class:
public class Foo<T>
public List<String> list = new ArrayList<>();
that I'm passing as a parameter to a method.
I have a problem understanding why here the type String
isn't resolved:
public void test(Foo t)
t.list.get(0).contains("test");
and the t.list
is treated as List<Object>
while here everything works just fine:
public void test(Foo<?> t)
t.list.get(0).contains("test");
and t.list
is List<String>
.
java generics
Let's consider a class:
public class Foo<T>
public List<String> list = new ArrayList<>();
that I'm passing as a parameter to a method.
I have a problem understanding why here the type String
isn't resolved:
public void test(Foo t)
t.list.get(0).contains("test");
and the t.list
is treated as List<Object>
while here everything works just fine:
public void test(Foo<?> t)
t.list.get(0).contains("test");
and t.list
is List<String>
.
java generics
java generics
asked 2 hours ago


Jakubs
507
507
Murat has answered your question, but you are aware that the<T>
inFoo<T>
is redundant, right?
– Michael
2 hours ago
@Michael yes, it was just for the purpose of giving an example where theT
isn't used for the actual field type.
– Jakubs
2 hours ago
1
Possible duplicate of Compiler error on Java generic interface with a List<> method
– Oleksandr
1 hour ago
@Oleksandr in fact both questions are about the same problem but approach it from a different angle. Facing my problem and not knowing the solution I would be unable to understand the underlying reason behind both.
– Jakubs
1 min ago
add a comment |Â
Murat has answered your question, but you are aware that the<T>
inFoo<T>
is redundant, right?
– Michael
2 hours ago
@Michael yes, it was just for the purpose of giving an example where theT
isn't used for the actual field type.
– Jakubs
2 hours ago
1
Possible duplicate of Compiler error on Java generic interface with a List<> method
– Oleksandr
1 hour ago
@Oleksandr in fact both questions are about the same problem but approach it from a different angle. Facing my problem and not knowing the solution I would be unable to understand the underlying reason behind both.
– Jakubs
1 min ago
Murat has answered your question, but you are aware that the
<T>
in Foo<T>
is redundant, right?– Michael
2 hours ago
Murat has answered your question, but you are aware that the
<T>
in Foo<T>
is redundant, right?– Michael
2 hours ago
@Michael yes, it was just for the purpose of giving an example where the
T
isn't used for the actual field type.– Jakubs
2 hours ago
@Michael yes, it was just for the purpose of giving an example where the
T
isn't used for the actual field type.– Jakubs
2 hours ago
1
1
Possible duplicate of Compiler error on Java generic interface with a List<> method
– Oleksandr
1 hour ago
Possible duplicate of Compiler error on Java generic interface with a List<> method
– Oleksandr
1 hour ago
@Oleksandr in fact both questions are about the same problem but approach it from a different angle. Facing my problem and not knowing the solution I would be unable to understand the underlying reason behind both.
– Jakubs
1 min ago
@Oleksandr in fact both questions are about the same problem but approach it from a different angle. Facing my problem and not knowing the solution I would be unable to understand the underlying reason behind both.
– Jakubs
1 min ago
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
3
down vote
accepted
When using Foo t
, t
is a Raw Type so its non-static, non-inherited members, like the list
in above code, are also raw types. Here the relevant part of the Java Language Specification (see above link):
To facilitate interfacing with non-generic legacy code, it is possible to use as a type the erasure (§4.6) of a parameterized type (§4.5) or the erasure of an array type (§10.1) whose element type is a parameterized type. Such a type is called a raw type.
More precisely, a raw type is defined to be one of:
. . .
A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.
Just declare the list
as static
and the compiler will always assume it being a List
of String
(only for testing).
On the other side, Foo<?>
is not a raw type, it is a generic type and consequently the list
is also not considered a raw type.
And an advice later on that page:
The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.
Note: Type Erasure and generated byte-code is the same in both cases...
add a comment |Â
up vote
6
down vote
That's how Type Erasure works.
Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
Since your method accepts a raw type, the compiler applies the type erasure by erasing the type String
and replace it with Object
. That's why contains
is not recognized since Object
does not have that method call.
By supplying <?>
you provide a bounded type and that will be used for the type erasure. There the compiler will recognize contains
since String
has it.
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
When using Foo t
, t
is a Raw Type so its non-static, non-inherited members, like the list
in above code, are also raw types. Here the relevant part of the Java Language Specification (see above link):
To facilitate interfacing with non-generic legacy code, it is possible to use as a type the erasure (§4.6) of a parameterized type (§4.5) or the erasure of an array type (§10.1) whose element type is a parameterized type. Such a type is called a raw type.
More precisely, a raw type is defined to be one of:
. . .
A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.
Just declare the list
as static
and the compiler will always assume it being a List
of String
(only for testing).
On the other side, Foo<?>
is not a raw type, it is a generic type and consequently the list
is also not considered a raw type.
And an advice later on that page:
The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.
Note: Type Erasure and generated byte-code is the same in both cases...
add a comment |Â
up vote
3
down vote
accepted
When using Foo t
, t
is a Raw Type so its non-static, non-inherited members, like the list
in above code, are also raw types. Here the relevant part of the Java Language Specification (see above link):
To facilitate interfacing with non-generic legacy code, it is possible to use as a type the erasure (§4.6) of a parameterized type (§4.5) or the erasure of an array type (§10.1) whose element type is a parameterized type. Such a type is called a raw type.
More precisely, a raw type is defined to be one of:
. . .
A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.
Just declare the list
as static
and the compiler will always assume it being a List
of String
(only for testing).
On the other side, Foo<?>
is not a raw type, it is a generic type and consequently the list
is also not considered a raw type.
And an advice later on that page:
The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.
Note: Type Erasure and generated byte-code is the same in both cases...
add a comment |Â
up vote
3
down vote
accepted
up vote
3
down vote
accepted
When using Foo t
, t
is a Raw Type so its non-static, non-inherited members, like the list
in above code, are also raw types. Here the relevant part of the Java Language Specification (see above link):
To facilitate interfacing with non-generic legacy code, it is possible to use as a type the erasure (§4.6) of a parameterized type (§4.5) or the erasure of an array type (§10.1) whose element type is a parameterized type. Such a type is called a raw type.
More precisely, a raw type is defined to be one of:
. . .
A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.
Just declare the list
as static
and the compiler will always assume it being a List
of String
(only for testing).
On the other side, Foo<?>
is not a raw type, it is a generic type and consequently the list
is also not considered a raw type.
And an advice later on that page:
The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.
Note: Type Erasure and generated byte-code is the same in both cases...
When using Foo t
, t
is a Raw Type so its non-static, non-inherited members, like the list
in above code, are also raw types. Here the relevant part of the Java Language Specification (see above link):
To facilitate interfacing with non-generic legacy code, it is possible to use as a type the erasure (§4.6) of a parameterized type (§4.5) or the erasure of an array type (§10.1) whose element type is a parameterized type. Such a type is called a raw type.
More precisely, a raw type is defined to be one of:
. . .
A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.
Just declare the list
as static
and the compiler will always assume it being a List
of String
(only for testing).
On the other side, Foo<?>
is not a raw type, it is a generic type and consequently the list
is also not considered a raw type.
And an advice later on that page:
The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.
Note: Type Erasure and generated byte-code is the same in both cases...
edited 20 mins ago
answered 39 mins ago
Carlos Heuberger
23.4k85077
23.4k85077
add a comment |Â
add a comment |Â
up vote
6
down vote
That's how Type Erasure works.
Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
Since your method accepts a raw type, the compiler applies the type erasure by erasing the type String
and replace it with Object
. That's why contains
is not recognized since Object
does not have that method call.
By supplying <?>
you provide a bounded type and that will be used for the type erasure. There the compiler will recognize contains
since String
has it.
add a comment |Â
up vote
6
down vote
That's how Type Erasure works.
Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
Since your method accepts a raw type, the compiler applies the type erasure by erasing the type String
and replace it with Object
. That's why contains
is not recognized since Object
does not have that method call.
By supplying <?>
you provide a bounded type and that will be used for the type erasure. There the compiler will recognize contains
since String
has it.
add a comment |Â
up vote
6
down vote
up vote
6
down vote
That's how Type Erasure works.
Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
Since your method accepts a raw type, the compiler applies the type erasure by erasing the type String
and replace it with Object
. That's why contains
is not recognized since Object
does not have that method call.
By supplying <?>
you provide a bounded type and that will be used for the type erasure. There the compiler will recognize contains
since String
has it.
That's how Type Erasure works.
Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
Since your method accepts a raw type, the compiler applies the type erasure by erasing the type String
and replace it with Object
. That's why contains
is not recognized since Object
does not have that method call.
By supplying <?>
you provide a bounded type and that will be used for the type erasure. There the compiler will recognize contains
since String
has it.
answered 2 hours ago


Murat Karagöz
12.7k32961
12.7k32961
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52403725%2fgeneric-without-type-as-method-parameter-cant-resolve-its-field-type%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Murat has answered your question, but you are aware that the
<T>
inFoo<T>
is redundant, right?– Michael
2 hours ago
@Michael yes, it was just for the purpose of giving an example where the
T
isn't used for the actual field type.– Jakubs
2 hours ago
1
Possible duplicate of Compiler error on Java generic interface with a List<> method
– Oleksandr
1 hour ago
@Oleksandr in fact both questions are about the same problem but approach it from a different angle. Facing my problem and not knowing the solution I would be unable to understand the underlying reason behind both.
– Jakubs
1 min ago