Java Generics Value.<SomeValue> - java

I had an interview test and saw the following code:
EDIT:
public class TestValue {
private Value<SomeValue> defaultValue;
#Test
public void Empty_Value_Has_No_Value() {
Assert.assertFalse(Value.<SomeValue> createEmptyValue()
.hasValue());
}
#Test
public void Default_Value_IsEmpty() {
Assert.assertEquals(Value.<SomeValue> createEmptyValue(),
defaultValue);
}
#Test
public void Non_Empty_Value_Has_Value() {
Assert.assertTrue(new Value<SomeValue>(true, new SomeValue())
.hasValue());
}
}
I had never seen Java generic like
Value.<SomeValue>
The test is to implement Value class with the given unit test code above.
I tried to figure out the Value method signature below (need implementation):
public interface Value<T> {
public boolean hasValue();
public Value<T> createEmptyValue();
}
Any one know, please help?
Thank you
EDIT: Should be like this according to answers below #marlon
public class Value<T> {
public boolean hasValue(){}
public static <M> Value<M> createEmptyValue(){}; //need <M>
}
The key syntax to know:
Value.<SomeValue> //ClassName.<Type>method
is way to invoke static method of a class with parameterized argument.
EDIT: according to #snipes83, syntax to invoke non-static method of a class with parameterized argument.
SomeObject.<Type>method

Value.<SomeValue> it's the way generics are represented for methods.
Using Google Guava's Optional as an example:
Optional<String> email = Optional.<String>of(strEmail);
See Generic Types - Invoking generic methods
Since interfaces cannot declare static methods (shame on you java), just declare your method as static and forget about the interface, like this:
class Value<T> {
public static <T> Value<T> createEmptyValue(){
return null;
}
}

Look at the class Test with the method getEmptyList below:
public class Test {
public <T> List<T> getEmptyList() {
return new ArrayList<T>();
}
}
It returns an empty List containing objects of type T.
If you use Test like this
Test t = new Test();
List<Integer> list = t.getEmptyList();
Then the type inference mechanism is able to infer the type parameter based on the variable type.
However if you need to use the return value of getEmptyList within a method invocation expression like in the following example where the method printList expects a single argument of type List<Integer>, then the type can not be infered from any variable type.
public void printList(List<Integer> list) {
for (int i : list) {
System.out.print(i);
}
}
printList(t.getEmptyList()); // This will FAIL.
In this case you need to specify the type using the following:
printList(t.<Integer>getEmptyList());

1) This is how generic methods are invoked. Refer >> http://docs.oracle.com/javase/tutorial/java/generics/methods.html
2) <SomeValue> in Value.<SomeValue> is optional. Compiler can infer the type. This is called TypeInference. Refer >> http://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html
Answer Updated:
3) Value.<SomeValue> createEmptyValue() is right and Value.<SomeValue>createEmptyValue() is right too. Both ways are legal. Just tested it. Didn't notice before.

Although Value is itself obviously typed ( based on the instance variable type of Value<SomeValue>), the static createEmptyValue() method is also typed.
A reasonable assumption, if naming conventions have been adhered to, is that SomeValue extends (or implements) Value.
Although there us no one correct answer, a likely possibility for the signature of Value is:
public class Value<T extend Value> {
public static <V extends Value> V createEmptyValue() {
// some impl
}
}

Related

Java not allowed to call recursive method with generic type?

public class ResourceAssembler<T extends BasedEntity> {
public Resource<T> toResource(T entity) {
ExtendsBasedEntity e = getExtendsBasedEntity();
toResource(e); //<----compile error
//some other code
}
}
public class ExtendsBasedEntity extends BasedEntity{}
But if you call it from the outside its fine
//some other class
new ResourceAssembler<ExtendsBasedEntity>().toResource(new ExtendsBasedEntity())
Why?
Error:(28, 25) java: incompatible types: spring.BasedEntity cannot be converted to T
T may not be ExtendsBasedEntity, but some other subtype of BaseEntity, hence the compile error.
One way to "fix" the problem, is to use a type token
public class ResourceAssembler<T extends BasedEntity> {
private final Class<T> type;
public ResourceAssembler(Class<T> type) {
this.type = type;
}
public Resource<T> toResource(T entity) {
toResource(type.newInstance());
//some other code
}
}
Assuming that works for you.
Let's create two classes extending BasedEntity and call them EBE1 and EBE2.
Now you create a ResourceAssembly object using EBE1 as the type parameter. But let's say that in the implementation of the toResource method you do something like return toResource(new EBE2());.
So the return type of toResource() is becoming Resource<EBE2> but that is wrong because according to the structure you should return Resource<EBE1>. And that's why the compile time error. And type safety instincts of Java kicks in.
If you want to do return a generic for the toResource method then you either have to pass in the entity object down as it is or change it to the concrete type that you are initializing it within and not use generic (although I don't know why would anyone use the second option, but it's a "solution" to make it "compile").
Also, on the outside when you declare it. You are not specifying the type parameter for ResourceAssembly and hence it's a raw one. Try to do it with a type param. You will have red squiggly lines there as well.
Here is an example:
static class Resource<T> {
}
static class BasedEntity {
}
static class ExtendsBasedEntity1 extends BasedEntity {
}
static class ExtendsBasedEntity2 extends BasedEntity {
}
static public class ResourceAssembler<T extends BasedEntity> {
public Resource<T> toResource(T entity) {
return toResource(new ExtendsBasedEntity1()); //<----compile error
}
}
public static void main(String[] args) {
new ResourceAssembler<ExtendsBasedEntity1>().toResource(new ExtendsBasedEntity1()); // <---- No errors or warnings. This is valid and legal
new ResourceAssembler<ExtendsBasedEntity2>().toResource(new ExtendsBasedEntity1()); // <----- red squiggly lines here
new ResourceAssembler().toResource(new ExtendsBasedEntity2()); // <--compiler warning about raw types but no error
}
If you anyhow need to make it work the way you want it to, then instead of returning Resource<T>, return Resource<ExtendsBasedEntity> because you are recursing inside a generic method and looks like you need an object of concrete type to go in as the parameter for the recursive call. So it would make sense to do so.
Or else, go with #Bohemian's approach and make sure that in the class declaration of the type that you are using, there is a no-args constructor or else you will be having InstantiationException.

Generic method java 6 <T> before return type

What is the difference between:
public <T> void createArray(T sample){
ArrayList<T> list = new ArrayList<T>();
list.add(sample);
}
and
public void createArray(T sample){
ArrayList<T> list = new ArrayList<T>();
list.add(sample);
}
I read that the method signature for using types should have <T> before the return type but how come I am still able to create the method without the <T>? What is the implication if I do or do not put it?
In the second method, the type parameter would be typically defined in the class declaration to which the method belongs:
class MyClass<T> {
public void createArray(T sample){
ArrayList<T> list = new ArrayList<T>();
list.add(sample);
}
...
}
So the second method belongs to a generic type.
The first method is a generic method because it defines its own type parameter.
In the first case, the generic parameter T is defined for the method. Other methods may have a different T.
In the second case, the generic parameter T is defined for the class or interface. All methods within that class or interface must have the same T.
Defining a class-wide generic allows you to enforce the same type parameter on many methods. You can also have fields of the generic type. See ArrayList<t> for an example.
From the second example, I am guessing this method is defined in a generic class something like this:
class SomeClass<T> {
public void createArray(T sample){ ... }
}
The difference between the first and second example is that in the first example, the T is effectively a "local" type variable. You could give it a different name, e.g. S, to make it a little bit clearer:
class SomeClass<T> {
public <S> void createArray(S sample){ ... }
}
So, S and T are both type variables, but are unrelated. T is defined at class scope, and so can be used to refer to the same type amongst all methods in the class; S is defined only at method scope.
By using the name T instead of S, you are hiding the class-level type variable, T. This means that, for example, the following would not work:
class SomeClass<T> {
public T getWotsit() { ... }
public <T> void createArray(T sample){
T wotsit = getWotsit();
}
}
because the T in the signature of getWotsit and the T in the variable declaration T wotsit potentially refer to different types; this is more clear if you use the name S to write the equivalent code:
class SomeClass<T> {
public T getWotsit() { ... }
public <S> void createArray(S sample){
S wotsit = getWotsit();
}
}
As far as I'm aware, there is no way to refer to the class-level type variable if you've defined a method-level type variable with the same name.
However, both of the following would be fine:
class SomeClass<T> {
public T getWotsit() { ... }
// No additional type variable, so T is the class-level type variable.
public void createArray(T sample){
T wotsit = getWotsit();
}
}
class SomeClass<T> {
public T getWotsit() { ... }
// Type variable has different name, so `T` is the class-level
// type variable.
public <S> void createArray(T sample){
T wotsit = getWotsit();
}
}
In case of public void createArray(T sample) where T is defined in class definition MyClass<T> is generic for the class
For public <T> void createArray(T sample){ , T is local generic for method and is not related to T in MyClass<T>, this T could be anything X,Y,Z. If you remove <T> before void, it is now <T> from MyClass<T> and cannot be X,Y,Z

Rationale behind not providing / providing <T> before return type of a method/constructor in Java for Generic classes

What is the rationale behind not providing / providing before return type of a method/constructor in Java for Generic classes?
I cannot get my head around it.
Sometimes it wants it and sometimes not. Do we ever need it for constructors?
The rules seem to be random and cannot find a logical explanation for it.
<T> in the method definition means that the type is defined in the method signature, and used only within that method.
Put <T> before the return type of a method when you want a generic associated with that method, instead of the containing class.
class Foo {
// T is associated with the method
<T> T stuff(T x) ...
}
class Bar<T> {
// T is associated with the class
T stuff(T x) ...
}
class Baz<T> {
// S is associated with the method, T with the class
<S> T stuff(S x) ...
<S> S otherStuff(T x) ...
}
class WTF<T> {
// Legal, but redundant
<T> T stuff(T x) ...
}
Constructors are no different. It is possible to put generics in constructors, as in
class Weird {
// T is associated with the constructor only
<T> Weird(T arg) ...
}
This would be unusual, though. It is much more common to see constructors use class-level generics, as in
class Normal<T> {
// T is associated with the class, as usual
Normal(T arg) ...
}
Sometimes it wants it and sometimes
not.
In the following case, it is not necessary, because the generic type is declared/defined as part of the class definition:
public class Example<T> {
public T generateItem() { return null; };
}
In the following case, it is necessary, because the generic type is NOT declared/defined as part of the class definition (or elsewhere):
public class Example {
public <T> T generateItem() { return null; };
}
The rule is: is it declared somewhere in the context or not? That's it!

Calling a static method using generic type

No static member can use a type parameter, but is it possible to call a static member using the generic type parameter? For example:-
abstract class Agent<A>{
void callAgent();
Agent(){
A.add();
}
}
Here add() is a static method.
There are some C# questions and answers on a similar topic but I'm not too sure how to go about it in Java.
No you cannot do it if A is a generic type. (Bozho answered to fast :) and probably thought A was concrete type.
What will work is the following.
abstract class Agent extends Blah<ConcreteA>{
void callAgent();
Agent() {
ConcreteA.add();
}
}
but it's probably not what you want to do.
After reading your comments it sounds like what you really want to do is:
abstract class Agent<A extends SomeClassThatSupportsAdd> {
void callAgent();
protected abstract A createNew();
Agent() {
A a = createNew();
A.add();
}
}
Your subclasses will have to override createNew().
If you still do not like that you can take a look at AspectJ which will allow you to do some constructor magic (see how spring does #Configurable) but that gets far trickier and complicates things.
Another option is Scala. Java does not do inheritance on static methods so you can't get parameterized modules (groups of functions in some languages this is called a functor ... ocaml). However Scala supports a singleton "object" that does allow for parametric functional polymorphic inheritance.
No, you cannot. The compiler does not know A (which resolves to Object) has the add method.
And you shouldn't need to invoke static methods on generic types in the first place. If you want specific behaviour for each type, define it as non-static, use extends BaseClass in the generics declaration, and invoke it.
Technically, you can also invoke a static method that way, but it's ugly:
class Base {
public static void add() { }
}
class Foo<A extends Base> {
void bar() {
A a = null; // you can't use new A()!
a.add();
}
}
This is not possible because the A type will not necessarily contain an add() method. The compiler will not permit this, because it can't guarantee that it will work.
In fact, you can invoke a static method on a type parameter (although it isn't done dynamically).
Try this:
public class Main<T extends Collections> {
public static void main(String[] args) {
new Main<>().foo();
}
void foo() {
List<Integer> list = Arrays.asList(2, 3, 1);
T.sort(list);
System.out.println(list);
}
}
I have no idea why the language designers decided it was a good idea to allow this.
It is handy to get a value from an enum you don't know beforehand.
public static <T extends Enum<T>> T enumFromName(String name, Class<T> clazz) {
return StringUtils.isEmpty(value) ? null : T.valueOf(clazz, name);
}
Having:
enum ProductType { FOOD, ELECTRONICS, ... }
You can do:
ProductType p = enumFromName("FOOD", ProductType.class);
I guess you can also take advantage of this in your own classes, although I would not recommend using static too much.
You can use reflection for calling static method of class T. For example:
public Agent<T>{
private final Class<T> clazz;
public Agent(Class<T> clazz){
this.clazz = clazz;
executeAddMethodOfGenericClass();
}
public void executeAddMethodOfGenericClass() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Method method = clazz.getMethod("add");
method.invoke(null);
}
}
But i can get exception. Be careful.

How to iterate over a wildcard generic?

How can I iterate over a wildcard generic? Basically I would like to inline the following method:
private <T extends Fact> void iterateFacts(FactManager<T> factManager) {
for (T fact : factManager) {
factManager.doSomething(fact);
}
}
If this code is in a separate method as shown, it works because the generic method context allows to define a wildcard type (here T) over which one can iterate. If one tries to inline this method, the method context is gone and one cannot iterate over a wildcard type anymore. Even doing this automatically in Eclipse fails with the following (uncompilable) code:
...
for (FactManager<?> factManager : factManagers) {
...
for ( fact : factManager) {
factManager.doSomething(fact);
}
...
}
...
My question is simply: Is there a way to put some wildcard type one can iterate over, or is this a limitation of generics (meaning it is impossible to do so)?
No. In situation like this, the workaround is to create a helper method.
The JLS has this example http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.10
public static void reverse(List<?> list) { rev(list);}
private static <T> void rev(List<T> list) { ... }
The issue is, we have a List<?> object. We know it must be a List<X> of some X, and we'd like to write code using X. Internally compiler does convert the wildcard to a type variable X, but Java language does not offer programmers a direct way to access it. But if there's a method accepting List<T>, we can pass the object to the method. Compiler infers that T=X and the call is good.
If there's no type erasure, X can be known at runtime, then Java would definitely give us a way to access X. However as of today since X isn't available at runtime, there's not much point. A purely synthetic way could be provided, which is unlikely to be simpler than the helper method workaround.
Type parameters can only defined on
types (i.e. classes/interfaces),
methods, and
constructors.
You would need a type parameter for a local block, which is not possible.
Yeah, I missed something like this sometimes, too.
But there is not really a problem with having the method non-inlined here - if it presents a performance bottleneck where inlining would help, Hotspot will inline it again (not caring about the type).
Additionally, having a separate method allows giving it a descriptive name.
Just an idea, if you need this often:
interface DoWithFM {
void <T> run(FactManager<T> t);
}
...
for (FactManager<?> factManager : factManagers) {
...
new DoWithFM() { public <T> run(FactManager<T> factManager) {
for (T fact : factManager) {
factManager.doSomething(fact);
}
}.run(factManager);
...
}
...
You can always fall back to Object
for (FactManager<?> factManager : factManagers) {
...
for ( Object fact : factManager) {
factManager.doSomething(fact);
}
...
}
This, of course, is subject to what is the actual declaration of doSomething.
If doSomething is declared as this void doSomething( T fact ), then your recourse here would be to use a raw type and swallow unchecked warnings. If you can guarantee that FactManager can only have homogeneous Facts inserted, then that may be an OK solution.
for (FactManager factManager : factManagers) { // unchecked warning on this line
...
for ( Object fact : factManager) {
factManager.doSomething(fact);
}
...
}
Well, I can think of a way to do it using inner classes, because the inner class shares the type parameter with its enclosing type. Also, even using wildcards you could still process your collections thanks to wildcard capture conversion.
Let me create an example. This code compiles and runs fine. But I cannot be certain if the use of inner classes would be an issue for you.
//as you can see type parameter belongs to the enclosing class
public class FactManager<T> implements Iterable<FactManager<T>.Fact> {
private Collection<Fact> items = new ArrayList<Fact>();
public void doSomething(Fact fact) {
System.out.println(fact.getValue());
}
public void addFact(T value) {
this.items.add(new Fact(value));
}
#Override
public Iterator<Fact> iterator() {
return items.iterator();
}
public class Fact {
//inner class share its enclosing class type parameter
private T value;
public Fact(T value) {
this.value = value;
}
public T getValue() {
return this.value;
}
public void setValue(T value) {
this.value = value;
}
}
public static void main(String[] args) {
List<FactManager<String>> factManagers = new ArrayList<FactManager<String>>();
factManagers.add(new FactManager<String>());
factManagers.get(0).addFact("Obi-wan");
factManagers.get(0).addFact("Skywalker");
for(FactManager<? extends CharSequence> factManager : factManagers){
//process thanks to wildcard capture conversion
procesFactManager(factManager);
}
}
//Wildcard capture conversion can be used to process wildcard-based collections
public static <T> void procesFactManager(FactManager<T> factManager){
for(FactManager<T>.Fact fact : factManager){
factManager.doSomething(fact);
}
}
}
This is more precisely matched to the method you defined (that is, if you can call iterateFacts() with the FactManagers in factManagers, you know that the FactManager contain items that are some subclass of Fact).
for (FactManager<? extends Fact> factManager : factManagers) {
for (Fact fact : factManager) {
factManager.doSomething(fact);
}
}
I would tend to think, however, that you would declare FactManager to be generic for subtypes of Fact (just given the name of the class), e.g.
class FactManager<T extends Fact> implements Iterable<T> {
...
}
The Eclipse refactoring fails because it cannot infer the type of an object contained by FactManager<?>.

Categories

Resources