1 /*
2  * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*SAM types:
25          1. An interface that has a single abstract method
26          2. Having more than one distinct methods, but only one is "real", the others are overriden public methods in Object - example: Comparator<T>
27          3. Having more than one methods due to inheritance, but they have the same signature
28          4. Having more than one methods due to inheritance, but one of them has a subsignature of all other methods
29                 a) parameter types compatible
30                 b) return type substitutable
31                 c) thrown type not conflicting with the thrown clause of any other method
32                 d) mixed up
33          5. Type-dependent SAM types
34   non-SAM types:
35          6. An interface that has a single abstract method, which is also public method in Object
36          7. Having more than one methods due to inheritance, and none of them has a subsignature of all other methods
37 */
38 
39 import java.util.List;
40 import java.util.Collection;
41 import java.sql.SQLException;
42 import java.sql.SQLTransientException;
43 import java.util.concurrent.TimeoutException;
44 import java.io.*;
45 
getOldest(List<Number> list)46 interface A {int getOldest(List<Number> list);}
getOldest(List list)47 interface B {int getOldest(List list);}
getOldest(List<?> list)48 interface C {int getOldest(List<?> list);}
getOldest(List<Integer> list)49 interface D {int getOldest(List<Integer> list);}
getOldest(Collection<?> collection)50 interface E {int getOldest(Collection<?> collection);}
51 //Not SAM type, case #7
52 interface DE extends D, E {}
53 
getAge(Number n)54 interface Foo {int getAge(Number n);}
getAge(Integer i)55 interface Bar {int getAge(Integer i);}
56 //Not SAM type, case #7
57 interface FooBar extends Foo, Bar {}
58 
59 //Not SAM type, case #6
equals(Object o)60 interface Planet {boolean equals(Object o);}
61 
62 // SAM type interfaces:
63 // type #2:
64 //only one abstract non-Ojbect method getAge()
getAge(T t)65 interface Mars<T> extends Planet {int getAge(T t);}
66 //only one abstract non-Ojbect method increment()
67 interface Jupiter {
equals(Object o)68     boolean equals(Object o);
toString()69     String toString();
increment(int i)70     int increment(int i);
71 }
72 
73 // type #3:
getTotal(List<String> arg)74 interface X {int getTotal(List<String> arg);}
getTotal(List<String> strs)75 interface Y {int getTotal(List<String> strs);}
76 //SAM type ([List<String>], int, {})
77 interface XY extends X, Y {}
78 //SAM type ([List<String>], int, {})
79 interface XYZ extends X, Y, XY {}
80 
81 // type #4 a):
82 //SAM type ([List], int, {})
83 interface AB extends A, B {}
84 
85 // type #4 b):
getValue(String str)86 interface F {Number getValue(String str);}
getValue(String str)87 interface G {Integer getValue(String str);}
getValue(String str)88 interface H {Serializable getValue(String str);}
getValue(String str)89 interface I {Object getValue(String str);}
90 //SAM type ([String], Integer, {})
91 interface FGHI extends F, G, H, I {}
92 
getAll(String str)93 interface J {List<Number> getAll(String str);}
getAll(String str)94 interface K {List<?> getAll(String str);}
getAll(String str)95 interface L {List getAll(String str);}
getAll(String str)96 interface M {Collection getAll(String str);}
97 //SAM type ([String], List<Number>/List, {}) - the return type is flexible to some degree
98 interface JK extends J, K {}
99 //SAM type ([String], List<Number>/List, {})
100 interface JL extends J, L {}
101 //SAM type ([String], List<Number>/List, {})
102 interface JKL extends J, K, L {}
103 //SAM type ([String], List<Number>/List, {})
104 interface JKLM extends J, K, L, M {}
105 
106 // type #4 c):
getText(File f)107 interface N {String getText(File f) throws IOException;}
getText(File f)108 interface O {String getText(File f) throws FileNotFoundException;}
getText(File f)109 interface P {String getText(File f) throws NullPointerException;}
110 //SAM type ([File], String, {FileNotFoundException})
111 interface NO extends N, O {}
112 //SAM type ([File], String, {})
113 interface NOP extends N, O, P {}
114 
getAge(String s)115 interface Boo {int getAge(String s) throws IOException;}
getAge(String s)116 interface Doo {int getAge(String s) throws SQLException;}
117 //SAM type ([String], int, {})
118 interface BooDoo extends Boo, Doo {}
119 
120 // type #4 d):
m(Iterable<String> arg)121 interface Q {Iterable m(Iterable<String> arg);}
m(Iterable arg)122 interface R {Iterable<String> m(Iterable arg);}
123 //SAM type ([Iterable], Iterable<String>/Iterable, {})
124 interface QR extends Q, R {}
125 
foo(List<String> arg)126 interface U {Collection foo(List<String> arg) throws IOException, SQLTransientException;}
foo(List<String> arg)127 interface V {List<?> foo(List<String> arg) throws EOFException, SQLException, TimeoutException;}
foo(List arg)128 interface W {List<String> foo(List arg) throws Exception;}
129 //SAM type ([List<String>], List<String>/List, {EOFException, SQLTransientException})
130 interface UV extends U, V {}
131 // SAM type ([List], List<String>/List, {EOFException, SQLTransientException})
132 interface UVW extends U, V, W {}
133 
134 // type #5:
135 // Not a SAM because sam-ness depends on instantiation of type-variables
m(T arg)136 interface Qoo<T> {void m(T arg);}
m(S arg)137 interface Roo<S extends Number> {void m(S arg);}
138 interface QooRoo<T1, T2 extends Number, T3> extends Qoo<T1>, Roo<T2> {}
139