What is the point of allowing type witnesses on all method calls?how this kind of syntax is even possibleWhy does Java allow calling methods with type arguments that don't have type parameters?What do constructor type arguments mean when placed *before* the type?Generic method reference type specifying before/after :: operatorIssues relating to type parameters in Java method callsCan I make a constructor generic without making the class generic?How do I use reflection to call a generic method?How slow are Java exceptions?How do I make the method return type generic?How to get the type of T from a member of a generic class or method?Why does a static method on a generic type require a Type parameter?Method has the same erasure as another method in typeWhat is a raw type and why shouldn't we use it?How to call a method after a delay in AndroidWhat is the point of the diamond operator (<>) in Java 7?What is the point of “final class” in Java?

Explain how 'Sharing the burden' puzzle from Professor Layton and the Miracle Mask should be solved

Machine Learning Golf: Multiplication

Why do we need a bootloader separate than our application program in MCU's?

My players like to search everything. What do they find?

How to respond to someone who condemns behavior similar to what they exhibit?

Are there advantages in writing by hand over typing out a story?

What happens if the limit of 4 billion files was exceeded in an ext4 partition?

How to figure out layers of the atmosphere?

Chess problem: Make a crossword in 3 moves

Should I warn my boss I might take sick leave

Do I need to be legally qualified to install a Hive smart thermostat?

Minimizing medical costs with HSA

Does taking on an assistant professor position prevent me from doing post-docs later?

How to improve the size of cells in this table?

Is there a typical layout to blocking installed for backing in new construction framing?

Why is the order of my features changed when using readFeatures in OpenLayers v4.6.5?

CPA filed late returns, stating I would get money; IRS says they were filed too late

What/Where usage English vs Japanese

Can 4 Joy cons connect to the same Switch?

How to calculate a conditional PDF in mathematica?

Does the Defensive Duelist feat stack with the Warforged integrated protection?

How come having a Deathly Hallow is not a big deal?

What is exact meaning of “ich wäre gern”?

Bypass with wrong cvv of debit card and getting OTP



What is the point of allowing type witnesses on all method calls?


how this kind of syntax is even possibleWhy does Java allow calling methods with type arguments that don't have type parameters?What do constructor type arguments mean when placed *before* the type?Generic method reference type specifying before/after :: operatorIssues relating to type parameters in Java method callsCan I make a constructor generic without making the class generic?How do I use reflection to call a generic method?How slow are Java exceptions?How do I make the method return type generic?How to get the type of T from a member of a generic class or method?Why does a static method on a generic type require a Type parameter?Method has the same erasure as another method in typeWhat is a raw type and why shouldn't we use it?How to call a method after a delay in AndroidWhat is the point of the diamond operator (<>) in Java 7?What is the point of “final class” in Java?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








25















Say we have two methods like the following:



public static <T> T genericReturn() /*...*/ 
public static String stringReturn() /*...*/


In calling any method, you can supply the type witness regardless of whether or not there is any requirement:



String s;
s = Internet.<String>genericReturn(); //Type witness used in return type, returns a String
s = Internet.<Integer>stringReturn(); //Type witness ignored, returns a String


However I'm not seeing any realistic use for this in Java at all, unless the type cannot be inferred (which is usually indicative of a bigger issue). Additionally the fact that it is simply ignored when it is not appropriately used seems counterintuitive. So what's the point of having this in Java at all?










share|improve this question
























  • I'm surprised your first snippet even compiles, given that get() isn't a generic method. Will need to look into that a bit more. Where have you seen this kind of code? Perhaps it's the result of an odd decompiler?

    – Jon Skeet
    Jan 18 '15 at 21:15












  • Although the type argument is irrelevant - ExampleSuper sup = dataList.<String>get(0); compiles just as well.

    – Jon Skeet
    Jan 18 '15 at 21:16











  • @JonSkeet The return type for get is generic, it's bounded by the class' own defined generic modifier <E>

    – Rogue
    Jan 18 '15 at 21:18






  • 4





    But that doesn't make the method generic. The method itself has no type parameters; the type parameter is on the class. Specifying a type argument for a method with no type parameters makes no sense to me.

    – Jon Skeet
    Jan 18 '15 at 21:18












  • @JonSkeet After a little testing, it seems you can add the "parameterizing" to any method call provided the cast is legal (upcasting).

    – Rogue
    Jan 18 '15 at 21:20

















25















Say we have two methods like the following:



public static <T> T genericReturn() /*...*/ 
public static String stringReturn() /*...*/


In calling any method, you can supply the type witness regardless of whether or not there is any requirement:



String s;
s = Internet.<String>genericReturn(); //Type witness used in return type, returns a String
s = Internet.<Integer>stringReturn(); //Type witness ignored, returns a String


However I'm not seeing any realistic use for this in Java at all, unless the type cannot be inferred (which is usually indicative of a bigger issue). Additionally the fact that it is simply ignored when it is not appropriately used seems counterintuitive. So what's the point of having this in Java at all?










share|improve this question
























  • I'm surprised your first snippet even compiles, given that get() isn't a generic method. Will need to look into that a bit more. Where have you seen this kind of code? Perhaps it's the result of an odd decompiler?

    – Jon Skeet
    Jan 18 '15 at 21:15












  • Although the type argument is irrelevant - ExampleSuper sup = dataList.<String>get(0); compiles just as well.

    – Jon Skeet
    Jan 18 '15 at 21:16











  • @JonSkeet The return type for get is generic, it's bounded by the class' own defined generic modifier <E>

    – Rogue
    Jan 18 '15 at 21:18






  • 4





    But that doesn't make the method generic. The method itself has no type parameters; the type parameter is on the class. Specifying a type argument for a method with no type parameters makes no sense to me.

    – Jon Skeet
    Jan 18 '15 at 21:18












  • @JonSkeet After a little testing, it seems you can add the "parameterizing" to any method call provided the cast is legal (upcasting).

    – Rogue
    Jan 18 '15 at 21:20













25












25








25


7






Say we have two methods like the following:



public static <T> T genericReturn() /*...*/ 
public static String stringReturn() /*...*/


In calling any method, you can supply the type witness regardless of whether or not there is any requirement:



String s;
s = Internet.<String>genericReturn(); //Type witness used in return type, returns a String
s = Internet.<Integer>stringReturn(); //Type witness ignored, returns a String


However I'm not seeing any realistic use for this in Java at all, unless the type cannot be inferred (which is usually indicative of a bigger issue). Additionally the fact that it is simply ignored when it is not appropriately used seems counterintuitive. So what's the point of having this in Java at all?










share|improve this question
















Say we have two methods like the following:



public static <T> T genericReturn() /*...*/ 
public static String stringReturn() /*...*/


In calling any method, you can supply the type witness regardless of whether or not there is any requirement:



String s;
s = Internet.<String>genericReturn(); //Type witness used in return type, returns a String
s = Internet.<Integer>stringReturn(); //Type witness ignored, returns a String


However I'm not seeing any realistic use for this in Java at all, unless the type cannot be inferred (which is usually indicative of a bigger issue). Additionally the fact that it is simply ignored when it is not appropriately used seems counterintuitive. So what's the point of having this in Java at all?







java generics






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 28 '15 at 16:36







Rogue

















asked Jan 18 '15 at 21:12









RogueRogue

7,1783 gold badges29 silver badges54 bronze badges




7,1783 gold badges29 silver badges54 bronze badges












  • I'm surprised your first snippet even compiles, given that get() isn't a generic method. Will need to look into that a bit more. Where have you seen this kind of code? Perhaps it's the result of an odd decompiler?

    – Jon Skeet
    Jan 18 '15 at 21:15












  • Although the type argument is irrelevant - ExampleSuper sup = dataList.<String>get(0); compiles just as well.

    – Jon Skeet
    Jan 18 '15 at 21:16











  • @JonSkeet The return type for get is generic, it's bounded by the class' own defined generic modifier <E>

    – Rogue
    Jan 18 '15 at 21:18






  • 4





    But that doesn't make the method generic. The method itself has no type parameters; the type parameter is on the class. Specifying a type argument for a method with no type parameters makes no sense to me.

    – Jon Skeet
    Jan 18 '15 at 21:18












  • @JonSkeet After a little testing, it seems you can add the "parameterizing" to any method call provided the cast is legal (upcasting).

    – Rogue
    Jan 18 '15 at 21:20

















  • I'm surprised your first snippet even compiles, given that get() isn't a generic method. Will need to look into that a bit more. Where have you seen this kind of code? Perhaps it's the result of an odd decompiler?

    – Jon Skeet
    Jan 18 '15 at 21:15












  • Although the type argument is irrelevant - ExampleSuper sup = dataList.<String>get(0); compiles just as well.

    – Jon Skeet
    Jan 18 '15 at 21:16











  • @JonSkeet The return type for get is generic, it's bounded by the class' own defined generic modifier <E>

    – Rogue
    Jan 18 '15 at 21:18






  • 4





    But that doesn't make the method generic. The method itself has no type parameters; the type parameter is on the class. Specifying a type argument for a method with no type parameters makes no sense to me.

    – Jon Skeet
    Jan 18 '15 at 21:18












  • @JonSkeet After a little testing, it seems you can add the "parameterizing" to any method call provided the cast is legal (upcasting).

    – Rogue
    Jan 18 '15 at 21:20
















I'm surprised your first snippet even compiles, given that get() isn't a generic method. Will need to look into that a bit more. Where have you seen this kind of code? Perhaps it's the result of an odd decompiler?

– Jon Skeet
Jan 18 '15 at 21:15






I'm surprised your first snippet even compiles, given that get() isn't a generic method. Will need to look into that a bit more. Where have you seen this kind of code? Perhaps it's the result of an odd decompiler?

– Jon Skeet
Jan 18 '15 at 21:15














Although the type argument is irrelevant - ExampleSuper sup = dataList.<String>get(0); compiles just as well.

– Jon Skeet
Jan 18 '15 at 21:16





Although the type argument is irrelevant - ExampleSuper sup = dataList.<String>get(0); compiles just as well.

– Jon Skeet
Jan 18 '15 at 21:16













@JonSkeet The return type for get is generic, it's bounded by the class' own defined generic modifier <E>

– Rogue
Jan 18 '15 at 21:18





@JonSkeet The return type for get is generic, it's bounded by the class' own defined generic modifier <E>

– Rogue
Jan 18 '15 at 21:18




4




4





But that doesn't make the method generic. The method itself has no type parameters; the type parameter is on the class. Specifying a type argument for a method with no type parameters makes no sense to me.

– Jon Skeet
Jan 18 '15 at 21:18






But that doesn't make the method generic. The method itself has no type parameters; the type parameter is on the class. Specifying a type argument for a method with no type parameters makes no sense to me.

– Jon Skeet
Jan 18 '15 at 21:18














@JonSkeet After a little testing, it seems you can add the "parameterizing" to any method call provided the cast is legal (upcasting).

– Rogue
Jan 18 '15 at 21:20





@JonSkeet After a little testing, it seems you can add the "parameterizing" to any method call provided the cast is legal (upcasting).

– Rogue
Jan 18 '15 at 21:20












4 Answers
4






active

oldest

votes


















20














From the JLS §15.2.12.1:




  • If the method invocation includes explicit type arguments, and the member is a generic method, then the number of type arguments is equal to the number of type parameters of the method.

This clause implies that a non-generic method may be potentially applicable to an invocation that supplies explicit type arguments. Indeed, it may turn out to be applicable. In such a case, the type arguments will simply be ignored.




It's followed by justification




This rule stems from issues of compatibility and principles of substitutability. Since interfaces or superclasses may be generified independently of their subtypes, we may override a generic method with a non-generic one. However, the overriding (non-generic) method must be applicable to calls to the generic method, including calls that explicitly pass type arguments. Otherwise the subtype would not be substitutable for its generified supertype.




Along this line of reasoning, let's construct an example. Suppose in Java 1.4, JDK has a class



public class Foo

/** check obj, and return it */
public Object check(Object obj) ...



Some user wrote a proprietary class that extends Foo and overrides the check method



public class MyFoo extends Foo

public Object check(Object obj) ...



When Java 1.5 introduced generics, Foo.check is generified as



 public <T> T check(T obj)


The ambitious backward comparability goal requires that MyFoo still compiles in Java 1.5 without modification; and MyFoo.check[Object->Object] is still an overriding method of Foo.check[T->T].



Now, according to aforementioned justification, since this compiles:



 MyFoo myFoo = new MyFoo();

((Foo)myFoo).<String>check("");


This must compile too:



 myFoo.<String>check("");


even though MyFoo.check is not generic.




That sounds like a stretch. But even if we buy that argument, the solution is still too broad and overreaching. JLS could've tighten it up so that myFoo.<String,String>check and obj.<Blah>toString() are illegal, because type parameter arity doesn't match. They probably didn't have time to iron it out so they just took a simple route.






share|improve this answer




















  • 1





    That explains why it's valid (although not why the language is designed that way - it's very odd, IMO) but it doesn't explain why anyone would use it. My understanding is that that's the main thrust of the question.

    – Jon Skeet
    Jan 18 '15 at 21:28











  • I noticed the ignoring in my testing on the updated question, heh. But more or less, why is it that this exists?

    – Rogue
    Jan 18 '15 at 21:29






  • 7





    The reason why this is allowed may be similar to why static methods can be invoked over an instance. It allows existing code to keep compiling after the method is un-generified.

    – Marko Topolnik
    Jan 18 '15 at 21:58






  • 2





    @MarkoTopolnik: Or alternatively, may allow code to take advantage of generic version of a method when it exists, while also being usable with a non-generic method. This could be helpful in scenarios involving inheritance, or in scenarios where consumers of some code might be using it with different versions of a library (some of which would use generics, and some of which wouldn't).

    – supercat
    Jan 20 '15 at 23:23






  • 1





    @supercat I've marked my answer as community wiki. Please feel free to edit the answer to reflect your comment.

    – arshajii
    Jan 22 '15 at 1:47


















4














You need the type witness (the type in the diamond) when type inference will not work (see http://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html)



The example given for this is when daisy-chaining calls like:



processStringList(Collections.emptyList());


where processStringList is defined as:



void processStringList(List<String> stringList) 

// process stringList



This will result in an error because it cannot cast a List<Object> to a List<String>. Thus, the witness is required. Albeit, you could do this in multiple steps, but this can be far more convenient.






share|improve this answer




















  • 1





    emptyList is generic, but type arguments are even allowed on non-generic methods, which is the strange bit.

    – arshajii
    Jan 18 '15 at 21:45












  • Right, this is the use-case that the "type witness" was designed for. The question is about why it's allowed on non-generic methods, too. In the example of the original post, that would be the stringReturn method.

    – asteri
    Jan 24 '15 at 16:52



















2





+150









It is because of backward- and/or forward-compatibility (at source level).



Imagine something like the introduction of generic parameters for some classes in Swing in JDK 7. It might happen with methods too (even with restrictions). If something turned out to be a bad idea, you can remove them and the source using it would still compile. In my opinion that is the reason why this is allowed, even if it is not used.



The flexibility though is limited. If you introduced type parameters with n types, you cannot later change to m types (in a source compatible way) if m != 0 or m != n.



(I understand this might not answer your question as I am not the designer of Java, this is only my idea/opinion.)






share|improve this answer























  • This doesn't sound right. There has never been a goal of maintaining comparability for un-generification.

    – ZhongYu
    Aug 28 '15 at 3:27


















2














Wondering why "Type Witness" was thrown around in Java? :D



To understand this we should start the story from Type Inference.




Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable. The inference algorithm determines the types of the arguments and, if available, the type that the result is being assigned, or returned. Finally, the inference algorithm tries to find the most specific type that works with all of the arguments.




If the above algorithm is still not able to determine the type we have "Type Witness" to explicitly state what type we need. For example:



public class TypeWitnessTest 

public static void main(String[] args)
print(Collections.emptyList());


static void print(List<String> list)
System.out.println(list);




The above code does not compile:



TypeWitnessTest.java:11: error: method print in class TypeWitnessTest cannot be applied to given types;
print(Collections.emptyList());
^
required: List<String>
found: List<Object>
reason: actual argument List<Object> cannot be converted to List<String> by method invocation conversion
1 error


So, you have Type Witness to rescue from this:



public class TypeWitnessTest 

public static void main(String[] args)
print(Collections.<String>emptyList());


static void print(List<String> list)
System.out.println(list);




This is compilable and works fine, however this has been more improved in Java 8:
JEP 101: Generalized Target-Type Inference



PS: I started from fundamentals so that other StackOverflow readers can also benefit.



EDIT:



Type Witness on non-generic Witness!



public class InternetTest 
public static void main(String[] args)
String s;
s = Internet.<String>genericReturn(); //Witness used in return type, returns a string
s = Internet.<Integer>stringReturn(); //Witness ignored, returns a string



class Internet
public static <T> T genericReturn() return null;
public static String stringReturn() return null;



I tried to simulate @Rogue example using javac 1.6.0_65 but it fails compilation with following error:



javac InternetTest.java 
InternetTest.java:5: stringReturn() in Internet cannot be applied to <java.lang.Integer>()
s = Internet.<Integer>stringReturn(); //Witness ignored, returns a string
^
1 error


@Rogue: If you were using some prior version than I used, then do let me know your javac version. And if you were then it is not allowed now. :P






share|improve this answer

























  • Right, this is the use-case that the "type witness" was designed for. The question is about why it's allowed on non-generic methods, too. In the example of the original post, that would be the stringReturn method.

    – asteri
    Jan 24 '15 at 16:52












  • @asteri: Type Witness on non-generic methods! When I tried it never compiled with javac version 1.6.0_65

    – Dev Naruka
    Jan 24 '15 at 18:22











  • You need to use JDK 7.

    – asteri
    Jan 25 '15 at 22:20













Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f28014853%2fwhat-is-the-point-of-allowing-type-witnesses-on-all-method-calls%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























4 Answers
4






active

oldest

votes








4 Answers
4






active

oldest

votes









active

oldest

votes






active

oldest

votes









20














From the JLS §15.2.12.1:




  • If the method invocation includes explicit type arguments, and the member is a generic method, then the number of type arguments is equal to the number of type parameters of the method.

This clause implies that a non-generic method may be potentially applicable to an invocation that supplies explicit type arguments. Indeed, it may turn out to be applicable. In such a case, the type arguments will simply be ignored.




It's followed by justification




This rule stems from issues of compatibility and principles of substitutability. Since interfaces or superclasses may be generified independently of their subtypes, we may override a generic method with a non-generic one. However, the overriding (non-generic) method must be applicable to calls to the generic method, including calls that explicitly pass type arguments. Otherwise the subtype would not be substitutable for its generified supertype.




Along this line of reasoning, let's construct an example. Suppose in Java 1.4, JDK has a class



public class Foo

/** check obj, and return it */
public Object check(Object obj) ...



Some user wrote a proprietary class that extends Foo and overrides the check method



public class MyFoo extends Foo

public Object check(Object obj) ...



When Java 1.5 introduced generics, Foo.check is generified as



 public <T> T check(T obj)


The ambitious backward comparability goal requires that MyFoo still compiles in Java 1.5 without modification; and MyFoo.check[Object->Object] is still an overriding method of Foo.check[T->T].



Now, according to aforementioned justification, since this compiles:



 MyFoo myFoo = new MyFoo();

((Foo)myFoo).<String>check("");


This must compile too:



 myFoo.<String>check("");


even though MyFoo.check is not generic.




That sounds like a stretch. But even if we buy that argument, the solution is still too broad and overreaching. JLS could've tighten it up so that myFoo.<String,String>check and obj.<Blah>toString() are illegal, because type parameter arity doesn't match. They probably didn't have time to iron it out so they just took a simple route.






share|improve this answer




















  • 1





    That explains why it's valid (although not why the language is designed that way - it's very odd, IMO) but it doesn't explain why anyone would use it. My understanding is that that's the main thrust of the question.

    – Jon Skeet
    Jan 18 '15 at 21:28











  • I noticed the ignoring in my testing on the updated question, heh. But more or less, why is it that this exists?

    – Rogue
    Jan 18 '15 at 21:29






  • 7





    The reason why this is allowed may be similar to why static methods can be invoked over an instance. It allows existing code to keep compiling after the method is un-generified.

    – Marko Topolnik
    Jan 18 '15 at 21:58






  • 2





    @MarkoTopolnik: Or alternatively, may allow code to take advantage of generic version of a method when it exists, while also being usable with a non-generic method. This could be helpful in scenarios involving inheritance, or in scenarios where consumers of some code might be using it with different versions of a library (some of which would use generics, and some of which wouldn't).

    – supercat
    Jan 20 '15 at 23:23






  • 1





    @supercat I've marked my answer as community wiki. Please feel free to edit the answer to reflect your comment.

    – arshajii
    Jan 22 '15 at 1:47















20














From the JLS §15.2.12.1:




  • If the method invocation includes explicit type arguments, and the member is a generic method, then the number of type arguments is equal to the number of type parameters of the method.

This clause implies that a non-generic method may be potentially applicable to an invocation that supplies explicit type arguments. Indeed, it may turn out to be applicable. In such a case, the type arguments will simply be ignored.




It's followed by justification




This rule stems from issues of compatibility and principles of substitutability. Since interfaces or superclasses may be generified independently of their subtypes, we may override a generic method with a non-generic one. However, the overriding (non-generic) method must be applicable to calls to the generic method, including calls that explicitly pass type arguments. Otherwise the subtype would not be substitutable for its generified supertype.




Along this line of reasoning, let's construct an example. Suppose in Java 1.4, JDK has a class



public class Foo

/** check obj, and return it */
public Object check(Object obj) ...



Some user wrote a proprietary class that extends Foo and overrides the check method



public class MyFoo extends Foo

public Object check(Object obj) ...



When Java 1.5 introduced generics, Foo.check is generified as



 public <T> T check(T obj)


The ambitious backward comparability goal requires that MyFoo still compiles in Java 1.5 without modification; and MyFoo.check[Object->Object] is still an overriding method of Foo.check[T->T].



Now, according to aforementioned justification, since this compiles:



 MyFoo myFoo = new MyFoo();

((Foo)myFoo).<String>check("");


This must compile too:



 myFoo.<String>check("");


even though MyFoo.check is not generic.




That sounds like a stretch. But even if we buy that argument, the solution is still too broad and overreaching. JLS could've tighten it up so that myFoo.<String,String>check and obj.<Blah>toString() are illegal, because type parameter arity doesn't match. They probably didn't have time to iron it out so they just took a simple route.






share|improve this answer




















  • 1





    That explains why it's valid (although not why the language is designed that way - it's very odd, IMO) but it doesn't explain why anyone would use it. My understanding is that that's the main thrust of the question.

    – Jon Skeet
    Jan 18 '15 at 21:28











  • I noticed the ignoring in my testing on the updated question, heh. But more or less, why is it that this exists?

    – Rogue
    Jan 18 '15 at 21:29






  • 7





    The reason why this is allowed may be similar to why static methods can be invoked over an instance. It allows existing code to keep compiling after the method is un-generified.

    – Marko Topolnik
    Jan 18 '15 at 21:58






  • 2





    @MarkoTopolnik: Or alternatively, may allow code to take advantage of generic version of a method when it exists, while also being usable with a non-generic method. This could be helpful in scenarios involving inheritance, or in scenarios where consumers of some code might be using it with different versions of a library (some of which would use generics, and some of which wouldn't).

    – supercat
    Jan 20 '15 at 23:23






  • 1





    @supercat I've marked my answer as community wiki. Please feel free to edit the answer to reflect your comment.

    – arshajii
    Jan 22 '15 at 1:47













20












20








20







From the JLS §15.2.12.1:




  • If the method invocation includes explicit type arguments, and the member is a generic method, then the number of type arguments is equal to the number of type parameters of the method.

This clause implies that a non-generic method may be potentially applicable to an invocation that supplies explicit type arguments. Indeed, it may turn out to be applicable. In such a case, the type arguments will simply be ignored.




It's followed by justification




This rule stems from issues of compatibility and principles of substitutability. Since interfaces or superclasses may be generified independently of their subtypes, we may override a generic method with a non-generic one. However, the overriding (non-generic) method must be applicable to calls to the generic method, including calls that explicitly pass type arguments. Otherwise the subtype would not be substitutable for its generified supertype.




Along this line of reasoning, let's construct an example. Suppose in Java 1.4, JDK has a class



public class Foo

/** check obj, and return it */
public Object check(Object obj) ...



Some user wrote a proprietary class that extends Foo and overrides the check method



public class MyFoo extends Foo

public Object check(Object obj) ...



When Java 1.5 introduced generics, Foo.check is generified as



 public <T> T check(T obj)


The ambitious backward comparability goal requires that MyFoo still compiles in Java 1.5 without modification; and MyFoo.check[Object->Object] is still an overriding method of Foo.check[T->T].



Now, according to aforementioned justification, since this compiles:



 MyFoo myFoo = new MyFoo();

((Foo)myFoo).<String>check("");


This must compile too:



 myFoo.<String>check("");


even though MyFoo.check is not generic.




That sounds like a stretch. But even if we buy that argument, the solution is still too broad and overreaching. JLS could've tighten it up so that myFoo.<String,String>check and obj.<Blah>toString() are illegal, because type parameter arity doesn't match. They probably didn't have time to iron it out so they just took a simple route.






share|improve this answer















From the JLS §15.2.12.1:




  • If the method invocation includes explicit type arguments, and the member is a generic method, then the number of type arguments is equal to the number of type parameters of the method.

This clause implies that a non-generic method may be potentially applicable to an invocation that supplies explicit type arguments. Indeed, it may turn out to be applicable. In such a case, the type arguments will simply be ignored.




It's followed by justification




This rule stems from issues of compatibility and principles of substitutability. Since interfaces or superclasses may be generified independently of their subtypes, we may override a generic method with a non-generic one. However, the overriding (non-generic) method must be applicable to calls to the generic method, including calls that explicitly pass type arguments. Otherwise the subtype would not be substitutable for its generified supertype.




Along this line of reasoning, let's construct an example. Suppose in Java 1.4, JDK has a class



public class Foo

/** check obj, and return it */
public Object check(Object obj) ...



Some user wrote a proprietary class that extends Foo and overrides the check method



public class MyFoo extends Foo

public Object check(Object obj) ...



When Java 1.5 introduced generics, Foo.check is generified as



 public <T> T check(T obj)


The ambitious backward comparability goal requires that MyFoo still compiles in Java 1.5 without modification; and MyFoo.check[Object->Object] is still an overriding method of Foo.check[T->T].



Now, according to aforementioned justification, since this compiles:



 MyFoo myFoo = new MyFoo();

((Foo)myFoo).<String>check("");


This must compile too:



 myFoo.<String>check("");


even though MyFoo.check is not generic.




That sounds like a stretch. But even if we buy that argument, the solution is still too broad and overreaching. JLS could've tighten it up so that myFoo.<String,String>check and obj.<Blah>toString() are illegal, because type parameter arity doesn't match. They probably didn't have time to iron it out so they just took a simple route.







share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 25 at 18:38


























community wiki





8 revs, 4 users 50%
ZhongYu








  • 1





    That explains why it's valid (although not why the language is designed that way - it's very odd, IMO) but it doesn't explain why anyone would use it. My understanding is that that's the main thrust of the question.

    – Jon Skeet
    Jan 18 '15 at 21:28











  • I noticed the ignoring in my testing on the updated question, heh. But more or less, why is it that this exists?

    – Rogue
    Jan 18 '15 at 21:29






  • 7





    The reason why this is allowed may be similar to why static methods can be invoked over an instance. It allows existing code to keep compiling after the method is un-generified.

    – Marko Topolnik
    Jan 18 '15 at 21:58






  • 2





    @MarkoTopolnik: Or alternatively, may allow code to take advantage of generic version of a method when it exists, while also being usable with a non-generic method. This could be helpful in scenarios involving inheritance, or in scenarios where consumers of some code might be using it with different versions of a library (some of which would use generics, and some of which wouldn't).

    – supercat
    Jan 20 '15 at 23:23






  • 1





    @supercat I've marked my answer as community wiki. Please feel free to edit the answer to reflect your comment.

    – arshajii
    Jan 22 '15 at 1:47












  • 1





    That explains why it's valid (although not why the language is designed that way - it's very odd, IMO) but it doesn't explain why anyone would use it. My understanding is that that's the main thrust of the question.

    – Jon Skeet
    Jan 18 '15 at 21:28











  • I noticed the ignoring in my testing on the updated question, heh. But more or less, why is it that this exists?

    – Rogue
    Jan 18 '15 at 21:29






  • 7





    The reason why this is allowed may be similar to why static methods can be invoked over an instance. It allows existing code to keep compiling after the method is un-generified.

    – Marko Topolnik
    Jan 18 '15 at 21:58






  • 2





    @MarkoTopolnik: Or alternatively, may allow code to take advantage of generic version of a method when it exists, while also being usable with a non-generic method. This could be helpful in scenarios involving inheritance, or in scenarios where consumers of some code might be using it with different versions of a library (some of which would use generics, and some of which wouldn't).

    – supercat
    Jan 20 '15 at 23:23






  • 1





    @supercat I've marked my answer as community wiki. Please feel free to edit the answer to reflect your comment.

    – arshajii
    Jan 22 '15 at 1:47







1




1





That explains why it's valid (although not why the language is designed that way - it's very odd, IMO) but it doesn't explain why anyone would use it. My understanding is that that's the main thrust of the question.

– Jon Skeet
Jan 18 '15 at 21:28





That explains why it's valid (although not why the language is designed that way - it's very odd, IMO) but it doesn't explain why anyone would use it. My understanding is that that's the main thrust of the question.

– Jon Skeet
Jan 18 '15 at 21:28













I noticed the ignoring in my testing on the updated question, heh. But more or less, why is it that this exists?

– Rogue
Jan 18 '15 at 21:29





I noticed the ignoring in my testing on the updated question, heh. But more or less, why is it that this exists?

– Rogue
Jan 18 '15 at 21:29




7




7





The reason why this is allowed may be similar to why static methods can be invoked over an instance. It allows existing code to keep compiling after the method is un-generified.

– Marko Topolnik
Jan 18 '15 at 21:58





The reason why this is allowed may be similar to why static methods can be invoked over an instance. It allows existing code to keep compiling after the method is un-generified.

– Marko Topolnik
Jan 18 '15 at 21:58




2




2





@MarkoTopolnik: Or alternatively, may allow code to take advantage of generic version of a method when it exists, while also being usable with a non-generic method. This could be helpful in scenarios involving inheritance, or in scenarios where consumers of some code might be using it with different versions of a library (some of which would use generics, and some of which wouldn't).

– supercat
Jan 20 '15 at 23:23





@MarkoTopolnik: Or alternatively, may allow code to take advantage of generic version of a method when it exists, while also being usable with a non-generic method. This could be helpful in scenarios involving inheritance, or in scenarios where consumers of some code might be using it with different versions of a library (some of which would use generics, and some of which wouldn't).

– supercat
Jan 20 '15 at 23:23




1




1





@supercat I've marked my answer as community wiki. Please feel free to edit the answer to reflect your comment.

– arshajii
Jan 22 '15 at 1:47





@supercat I've marked my answer as community wiki. Please feel free to edit the answer to reflect your comment.

– arshajii
Jan 22 '15 at 1:47













4














You need the type witness (the type in the diamond) when type inference will not work (see http://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html)



The example given for this is when daisy-chaining calls like:



processStringList(Collections.emptyList());


where processStringList is defined as:



void processStringList(List<String> stringList) 

// process stringList



This will result in an error because it cannot cast a List<Object> to a List<String>. Thus, the witness is required. Albeit, you could do this in multiple steps, but this can be far more convenient.






share|improve this answer




















  • 1





    emptyList is generic, but type arguments are even allowed on non-generic methods, which is the strange bit.

    – arshajii
    Jan 18 '15 at 21:45












  • Right, this is the use-case that the "type witness" was designed for. The question is about why it's allowed on non-generic methods, too. In the example of the original post, that would be the stringReturn method.

    – asteri
    Jan 24 '15 at 16:52
















4














You need the type witness (the type in the diamond) when type inference will not work (see http://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html)



The example given for this is when daisy-chaining calls like:



processStringList(Collections.emptyList());


where processStringList is defined as:



void processStringList(List<String> stringList) 

// process stringList



This will result in an error because it cannot cast a List<Object> to a List<String>. Thus, the witness is required. Albeit, you could do this in multiple steps, but this can be far more convenient.






share|improve this answer




















  • 1





    emptyList is generic, but type arguments are even allowed on non-generic methods, which is the strange bit.

    – arshajii
    Jan 18 '15 at 21:45












  • Right, this is the use-case that the "type witness" was designed for. The question is about why it's allowed on non-generic methods, too. In the example of the original post, that would be the stringReturn method.

    – asteri
    Jan 24 '15 at 16:52














4












4








4







You need the type witness (the type in the diamond) when type inference will not work (see http://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html)



The example given for this is when daisy-chaining calls like:



processStringList(Collections.emptyList());


where processStringList is defined as:



void processStringList(List<String> stringList) 

// process stringList



This will result in an error because it cannot cast a List<Object> to a List<String>. Thus, the witness is required. Albeit, you could do this in multiple steps, but this can be far more convenient.






share|improve this answer















You need the type witness (the type in the diamond) when type inference will not work (see http://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html)



The example given for this is when daisy-chaining calls like:



processStringList(Collections.emptyList());


where processStringList is defined as:



void processStringList(List<String> stringList) 

// process stringList



This will result in an error because it cannot cast a List<Object> to a List<String>. Thus, the witness is required. Albeit, you could do this in multiple steps, but this can be far more convenient.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 18 '15 at 21:42

























answered Jan 18 '15 at 21:37









desilvaidesilvai

2431 silver badge7 bronze badges




2431 silver badge7 bronze badges







  • 1





    emptyList is generic, but type arguments are even allowed on non-generic methods, which is the strange bit.

    – arshajii
    Jan 18 '15 at 21:45












  • Right, this is the use-case that the "type witness" was designed for. The question is about why it's allowed on non-generic methods, too. In the example of the original post, that would be the stringReturn method.

    – asteri
    Jan 24 '15 at 16:52













  • 1





    emptyList is generic, but type arguments are even allowed on non-generic methods, which is the strange bit.

    – arshajii
    Jan 18 '15 at 21:45












  • Right, this is the use-case that the "type witness" was designed for. The question is about why it's allowed on non-generic methods, too. In the example of the original post, that would be the stringReturn method.

    – asteri
    Jan 24 '15 at 16:52








1




1





emptyList is generic, but type arguments are even allowed on non-generic methods, which is the strange bit.

– arshajii
Jan 18 '15 at 21:45






emptyList is generic, but type arguments are even allowed on non-generic methods, which is the strange bit.

– arshajii
Jan 18 '15 at 21:45














Right, this is the use-case that the "type witness" was designed for. The question is about why it's allowed on non-generic methods, too. In the example of the original post, that would be the stringReturn method.

– asteri
Jan 24 '15 at 16:52






Right, this is the use-case that the "type witness" was designed for. The question is about why it's allowed on non-generic methods, too. In the example of the original post, that would be the stringReturn method.

– asteri
Jan 24 '15 at 16:52












2





+150









It is because of backward- and/or forward-compatibility (at source level).



Imagine something like the introduction of generic parameters for some classes in Swing in JDK 7. It might happen with methods too (even with restrictions). If something turned out to be a bad idea, you can remove them and the source using it would still compile. In my opinion that is the reason why this is allowed, even if it is not used.



The flexibility though is limited. If you introduced type parameters with n types, you cannot later change to m types (in a source compatible way) if m != 0 or m != n.



(I understand this might not answer your question as I am not the designer of Java, this is only my idea/opinion.)






share|improve this answer























  • This doesn't sound right. There has never been a goal of maintaining comparability for un-generification.

    – ZhongYu
    Aug 28 '15 at 3:27















2





+150









It is because of backward- and/or forward-compatibility (at source level).



Imagine something like the introduction of generic parameters for some classes in Swing in JDK 7. It might happen with methods too (even with restrictions). If something turned out to be a bad idea, you can remove them and the source using it would still compile. In my opinion that is the reason why this is allowed, even if it is not used.



The flexibility though is limited. If you introduced type parameters with n types, you cannot later change to m types (in a source compatible way) if m != 0 or m != n.



(I understand this might not answer your question as I am not the designer of Java, this is only my idea/opinion.)






share|improve this answer























  • This doesn't sound right. There has never been a goal of maintaining comparability for un-generification.

    – ZhongYu
    Aug 28 '15 at 3:27













2





+150







2





+150



2




+150





It is because of backward- and/or forward-compatibility (at source level).



Imagine something like the introduction of generic parameters for some classes in Swing in JDK 7. It might happen with methods too (even with restrictions). If something turned out to be a bad idea, you can remove them and the source using it would still compile. In my opinion that is the reason why this is allowed, even if it is not used.



The flexibility though is limited. If you introduced type parameters with n types, you cannot later change to m types (in a source compatible way) if m != 0 or m != n.



(I understand this might not answer your question as I am not the designer of Java, this is only my idea/opinion.)






share|improve this answer













It is because of backward- and/or forward-compatibility (at source level).



Imagine something like the introduction of generic parameters for some classes in Swing in JDK 7. It might happen with methods too (even with restrictions). If something turned out to be a bad idea, you can remove them and the source using it would still compile. In my opinion that is the reason why this is allowed, even if it is not used.



The flexibility though is limited. If you introduced type parameters with n types, you cannot later change to m types (in a source compatible way) if m != 0 or m != n.



(I understand this might not answer your question as I am not the designer of Java, this is only my idea/opinion.)







share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 24 '15 at 16:20









Gábor BakosGábor Bakos

7,1809 gold badges29 silver badges46 bronze badges




7,1809 gold badges29 silver badges46 bronze badges












  • This doesn't sound right. There has never been a goal of maintaining comparability for un-generification.

    – ZhongYu
    Aug 28 '15 at 3:27

















  • This doesn't sound right. There has never been a goal of maintaining comparability for un-generification.

    – ZhongYu
    Aug 28 '15 at 3:27
















This doesn't sound right. There has never been a goal of maintaining comparability for un-generification.

– ZhongYu
Aug 28 '15 at 3:27





This doesn't sound right. There has never been a goal of maintaining comparability for un-generification.

– ZhongYu
Aug 28 '15 at 3:27











2














Wondering why "Type Witness" was thrown around in Java? :D



To understand this we should start the story from Type Inference.




Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable. The inference algorithm determines the types of the arguments and, if available, the type that the result is being assigned, or returned. Finally, the inference algorithm tries to find the most specific type that works with all of the arguments.




If the above algorithm is still not able to determine the type we have "Type Witness" to explicitly state what type we need. For example:



public class TypeWitnessTest 

public static void main(String[] args)
print(Collections.emptyList());


static void print(List<String> list)
System.out.println(list);




The above code does not compile:



TypeWitnessTest.java:11: error: method print in class TypeWitnessTest cannot be applied to given types;
print(Collections.emptyList());
^
required: List<String>
found: List<Object>
reason: actual argument List<Object> cannot be converted to List<String> by method invocation conversion
1 error


So, you have Type Witness to rescue from this:



public class TypeWitnessTest 

public static void main(String[] args)
print(Collections.<String>emptyList());


static void print(List<String> list)
System.out.println(list);




This is compilable and works fine, however this has been more improved in Java 8:
JEP 101: Generalized Target-Type Inference



PS: I started from fundamentals so that other StackOverflow readers can also benefit.



EDIT:



Type Witness on non-generic Witness!



public class InternetTest 
public static void main(String[] args)
String s;
s = Internet.<String>genericReturn(); //Witness used in return type, returns a string
s = Internet.<Integer>stringReturn(); //Witness ignored, returns a string



class Internet
public static <T> T genericReturn() return null;
public static String stringReturn() return null;



I tried to simulate @Rogue example using javac 1.6.0_65 but it fails compilation with following error:



javac InternetTest.java 
InternetTest.java:5: stringReturn() in Internet cannot be applied to <java.lang.Integer>()
s = Internet.<Integer>stringReturn(); //Witness ignored, returns a string
^
1 error


@Rogue: If you were using some prior version than I used, then do let me know your javac version. And if you were then it is not allowed now. :P






share|improve this answer

























  • Right, this is the use-case that the "type witness" was designed for. The question is about why it's allowed on non-generic methods, too. In the example of the original post, that would be the stringReturn method.

    – asteri
    Jan 24 '15 at 16:52












  • @asteri: Type Witness on non-generic methods! When I tried it never compiled with javac version 1.6.0_65

    – Dev Naruka
    Jan 24 '15 at 18:22











  • You need to use JDK 7.

    – asteri
    Jan 25 '15 at 22:20















2














Wondering why "Type Witness" was thrown around in Java? :D



To understand this we should start the story from Type Inference.




Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable. The inference algorithm determines the types of the arguments and, if available, the type that the result is being assigned, or returned. Finally, the inference algorithm tries to find the most specific type that works with all of the arguments.




If the above algorithm is still not able to determine the type we have "Type Witness" to explicitly state what type we need. For example:



public class TypeWitnessTest 

public static void main(String[] args)
print(Collections.emptyList());


static void print(List<String> list)
System.out.println(list);




The above code does not compile:



TypeWitnessTest.java:11: error: method print in class TypeWitnessTest cannot be applied to given types;
print(Collections.emptyList());
^
required: List<String>
found: List<Object>
reason: actual argument List<Object> cannot be converted to List<String> by method invocation conversion
1 error


So, you have Type Witness to rescue from this:



public class TypeWitnessTest 

public static void main(String[] args)
print(Collections.<String>emptyList());


static void print(List<String> list)
System.out.println(list);




This is compilable and works fine, however this has been more improved in Java 8:
JEP 101: Generalized Target-Type Inference



PS: I started from fundamentals so that other StackOverflow readers can also benefit.



EDIT:



Type Witness on non-generic Witness!



public class InternetTest 
public static void main(String[] args)
String s;
s = Internet.<String>genericReturn(); //Witness used in return type, returns a string
s = Internet.<Integer>stringReturn(); //Witness ignored, returns a string



class Internet
public static <T> T genericReturn() return null;
public static String stringReturn() return null;



I tried to simulate @Rogue example using javac 1.6.0_65 but it fails compilation with following error:



javac InternetTest.java 
InternetTest.java:5: stringReturn() in Internet cannot be applied to <java.lang.Integer>()
s = Internet.<Integer>stringReturn(); //Witness ignored, returns a string
^
1 error


@Rogue: If you were using some prior version than I used, then do let me know your javac version. And if you were then it is not allowed now. :P






share|improve this answer

























  • Right, this is the use-case that the "type witness" was designed for. The question is about why it's allowed on non-generic methods, too. In the example of the original post, that would be the stringReturn method.

    – asteri
    Jan 24 '15 at 16:52












  • @asteri: Type Witness on non-generic methods! When I tried it never compiled with javac version 1.6.0_65

    – Dev Naruka
    Jan 24 '15 at 18:22











  • You need to use JDK 7.

    – asteri
    Jan 25 '15 at 22:20













2












2








2







Wondering why "Type Witness" was thrown around in Java? :D



To understand this we should start the story from Type Inference.




Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable. The inference algorithm determines the types of the arguments and, if available, the type that the result is being assigned, or returned. Finally, the inference algorithm tries to find the most specific type that works with all of the arguments.




If the above algorithm is still not able to determine the type we have "Type Witness" to explicitly state what type we need. For example:



public class TypeWitnessTest 

public static void main(String[] args)
print(Collections.emptyList());


static void print(List<String> list)
System.out.println(list);




The above code does not compile:



TypeWitnessTest.java:11: error: method print in class TypeWitnessTest cannot be applied to given types;
print(Collections.emptyList());
^
required: List<String>
found: List<Object>
reason: actual argument List<Object> cannot be converted to List<String> by method invocation conversion
1 error


So, you have Type Witness to rescue from this:



public class TypeWitnessTest 

public static void main(String[] args)
print(Collections.<String>emptyList());


static void print(List<String> list)
System.out.println(list);




This is compilable and works fine, however this has been more improved in Java 8:
JEP 101: Generalized Target-Type Inference



PS: I started from fundamentals so that other StackOverflow readers can also benefit.



EDIT:



Type Witness on non-generic Witness!



public class InternetTest 
public static void main(String[] args)
String s;
s = Internet.<String>genericReturn(); //Witness used in return type, returns a string
s = Internet.<Integer>stringReturn(); //Witness ignored, returns a string



class Internet
public static <T> T genericReturn() return null;
public static String stringReturn() return null;



I tried to simulate @Rogue example using javac 1.6.0_65 but it fails compilation with following error:



javac InternetTest.java 
InternetTest.java:5: stringReturn() in Internet cannot be applied to <java.lang.Integer>()
s = Internet.<Integer>stringReturn(); //Witness ignored, returns a string
^
1 error


@Rogue: If you were using some prior version than I used, then do let me know your javac version. And if you were then it is not allowed now. :P






share|improve this answer















Wondering why "Type Witness" was thrown around in Java? :D



To understand this we should start the story from Type Inference.




Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable. The inference algorithm determines the types of the arguments and, if available, the type that the result is being assigned, or returned. Finally, the inference algorithm tries to find the most specific type that works with all of the arguments.




If the above algorithm is still not able to determine the type we have "Type Witness" to explicitly state what type we need. For example:



public class TypeWitnessTest 

public static void main(String[] args)
print(Collections.emptyList());


static void print(List<String> list)
System.out.println(list);




The above code does not compile:



TypeWitnessTest.java:11: error: method print in class TypeWitnessTest cannot be applied to given types;
print(Collections.emptyList());
^
required: List<String>
found: List<Object>
reason: actual argument List<Object> cannot be converted to List<String> by method invocation conversion
1 error


So, you have Type Witness to rescue from this:



public class TypeWitnessTest 

public static void main(String[] args)
print(Collections.<String>emptyList());


static void print(List<String> list)
System.out.println(list);




This is compilable and works fine, however this has been more improved in Java 8:
JEP 101: Generalized Target-Type Inference



PS: I started from fundamentals so that other StackOverflow readers can also benefit.



EDIT:



Type Witness on non-generic Witness!



public class InternetTest 
public static void main(String[] args)
String s;
s = Internet.<String>genericReturn(); //Witness used in return type, returns a string
s = Internet.<Integer>stringReturn(); //Witness ignored, returns a string



class Internet
public static <T> T genericReturn() return null;
public static String stringReturn() return null;



I tried to simulate @Rogue example using javac 1.6.0_65 but it fails compilation with following error:



javac InternetTest.java 
InternetTest.java:5: stringReturn() in Internet cannot be applied to <java.lang.Integer>()
s = Internet.<Integer>stringReturn(); //Witness ignored, returns a string
^
1 error


@Rogue: If you were using some prior version than I used, then do let me know your javac version. And if you were then it is not allowed now. :P







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 24 '15 at 18:30

























answered Jan 24 '15 at 15:48









Dev NarukaDev Naruka

1136 bronze badges




1136 bronze badges












  • Right, this is the use-case that the "type witness" was designed for. The question is about why it's allowed on non-generic methods, too. In the example of the original post, that would be the stringReturn method.

    – asteri
    Jan 24 '15 at 16:52












  • @asteri: Type Witness on non-generic methods! When I tried it never compiled with javac version 1.6.0_65

    – Dev Naruka
    Jan 24 '15 at 18:22











  • You need to use JDK 7.

    – asteri
    Jan 25 '15 at 22:20

















  • Right, this is the use-case that the "type witness" was designed for. The question is about why it's allowed on non-generic methods, too. In the example of the original post, that would be the stringReturn method.

    – asteri
    Jan 24 '15 at 16:52












  • @asteri: Type Witness on non-generic methods! When I tried it never compiled with javac version 1.6.0_65

    – Dev Naruka
    Jan 24 '15 at 18:22











  • You need to use JDK 7.

    – asteri
    Jan 25 '15 at 22:20
















Right, this is the use-case that the "type witness" was designed for. The question is about why it's allowed on non-generic methods, too. In the example of the original post, that would be the stringReturn method.

– asteri
Jan 24 '15 at 16:52






Right, this is the use-case that the "type witness" was designed for. The question is about why it's allowed on non-generic methods, too. In the example of the original post, that would be the stringReturn method.

– asteri
Jan 24 '15 at 16:52














@asteri: Type Witness on non-generic methods! When I tried it never compiled with javac version 1.6.0_65

– Dev Naruka
Jan 24 '15 at 18:22





@asteri: Type Witness on non-generic methods! When I tried it never compiled with javac version 1.6.0_65

– Dev Naruka
Jan 24 '15 at 18:22













You need to use JDK 7.

– asteri
Jan 25 '15 at 22:20





You need to use JDK 7.

– asteri
Jan 25 '15 at 22:20

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f28014853%2fwhat-is-the-point-of-allowing-type-witnesses-on-all-method-calls%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript