2017-07-10 16:01:56 +00:00
|
|
|
import java.util.*;
|
|
|
|
|
2015-05-04 02:57:38 +00:00
|
|
|
public class InvokeDynamic {
|
2015-08-06 19:24:06 +00:00
|
|
|
private final int foo;
|
|
|
|
|
|
|
|
private InvokeDynamic(int foo) {
|
|
|
|
this.foo = foo;
|
|
|
|
}
|
2016-12-05 03:53:40 +00:00
|
|
|
|
2015-08-05 21:55:52 +00:00
|
|
|
private interface Operation {
|
|
|
|
int operate(int a, int b);
|
|
|
|
}
|
2015-05-04 02:57:38 +00:00
|
|
|
|
2016-12-05 03:53:40 +00:00
|
|
|
private interface Operation2 {
|
|
|
|
long operate(long a, int b);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static class Pair<A, B> {
|
|
|
|
public final A first;
|
|
|
|
public final B second;
|
|
|
|
|
|
|
|
public Pair(A first, B second) {
|
|
|
|
this.first = first;
|
|
|
|
this.second = second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private interface Supplier<T> extends java.io.Serializable {
|
|
|
|
T get();
|
|
|
|
}
|
|
|
|
|
2017-07-10 16:01:56 +00:00
|
|
|
private interface Consumer<T> {
|
|
|
|
void accept(T obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
private interface Function<T, R> {
|
|
|
|
R apply(T obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
private interface BiFunction<T, U, R> {
|
|
|
|
R apply(T t, U u);
|
|
|
|
}
|
|
|
|
|
|
|
|
private interface GetLong {
|
|
|
|
long get(long l);
|
|
|
|
}
|
|
|
|
|
|
|
|
private interface GetDouble {
|
|
|
|
double get(double d);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static class LongHolder implements GetLong {
|
|
|
|
@Override
|
|
|
|
public long get(long l) {
|
|
|
|
return l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static class DoubleHolder implements GetDouble {
|
|
|
|
@Override
|
|
|
|
public double get(double d) {
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-05 21:55:52 +00:00
|
|
|
private static void expect(boolean v) {
|
|
|
|
if (! v) throw new RuntimeException();
|
|
|
|
}
|
2016-12-05 03:53:40 +00:00
|
|
|
|
2015-05-04 02:57:38 +00:00
|
|
|
public static void main(String[] args) {
|
2015-08-05 21:55:52 +00:00
|
|
|
int c = 4;
|
|
|
|
Operation op = (a, b) -> a + b - c;
|
2015-08-06 19:24:06 +00:00
|
|
|
expect(op.operate(2, 3) == (2 + 3) - 4);
|
|
|
|
|
2015-08-06 23:22:14 +00:00
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
|
|
new InvokeDynamic(i).test();
|
|
|
|
}
|
2015-08-06 19:24:06 +00:00
|
|
|
}
|
|
|
|
|
2017-01-19 17:27:08 +00:00
|
|
|
private interface Foo extends java.io.Serializable {
|
|
|
|
void someFunction(Integer a, Integer b, String s);
|
|
|
|
}
|
|
|
|
|
|
|
|
private interface UnboxedSerializable extends java.io.Serializable {
|
|
|
|
int add(int a, int b);
|
|
|
|
}
|
|
|
|
|
|
|
|
private interface Unboxed {
|
|
|
|
int add(int a, int b);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void requiresBridge(Number a, Object... rest) {
|
|
|
|
String s = "" + a;
|
|
|
|
for (Object r : rest) {
|
|
|
|
s += r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static Integer addBoxed(Integer a, Integer b) {
|
|
|
|
return a + b;
|
|
|
|
}
|
|
|
|
|
|
|
|
private interface Marker {
|
|
|
|
}
|
|
|
|
|
2015-08-06 19:24:06 +00:00
|
|
|
private void test() {
|
2016-12-05 03:53:40 +00:00
|
|
|
{ int c = 2;
|
|
|
|
Operation op = (a, b) -> ((a + b) * c) - foo;
|
|
|
|
expect(op.operate(2, 3) == ((2 + 3) * 2) - foo);
|
|
|
|
}
|
|
|
|
|
|
|
|
{ int c = 2;
|
|
|
|
Operation2 op = (a, b) -> ((a + b) * c) - foo;
|
|
|
|
expect(op.operate(2, 3) == ((2 + 3) * 2) - foo);
|
|
|
|
}
|
|
|
|
|
|
|
|
{ Supplier<Pair<Long, Double>> s = () -> new Pair<Long, Double>(42L, 77.1D);
|
|
|
|
expect(s.get().first == 42L);
|
|
|
|
expect(s.get().second == 77.1D);
|
|
|
|
}
|
2016-12-07 17:23:13 +00:00
|
|
|
|
|
|
|
{ double[] a = new double[] { 3.14D };
|
|
|
|
Supplier<Pair<Long, Double>> s = () -> new Pair<Long, Double>(42L, a[0]);
|
|
|
|
expect(s.get().first == 42L);
|
|
|
|
expect(s.get().second == 3.14D);
|
|
|
|
}
|
2017-01-19 17:27:08 +00:00
|
|
|
|
|
|
|
{ Foo s = this::requiresBridge;
|
|
|
|
s.someFunction(1, 2, "");
|
|
|
|
}
|
|
|
|
|
2017-07-10 16:01:56 +00:00
|
|
|
{ Consumer<String> c = System.out::println;
|
|
|
|
c.accept("invoke virtual");
|
|
|
|
}
|
|
|
|
|
|
|
|
{ Function<CharSequence, String> f = CharSequence::toString;
|
|
|
|
expect(f.apply("invoke interface") == "invoke interface");
|
|
|
|
}
|
|
|
|
|
|
|
|
{ Function<CharSequence, Integer> f = CharSequence::length;
|
|
|
|
expect(f.apply("invoke interface") == 16);
|
|
|
|
}
|
|
|
|
|
|
|
|
{ BiFunction<CharSequence, Integer, Character> f = CharSequence::charAt;
|
|
|
|
String data = "0123456789";
|
|
|
|
for (int i = 0; i < data.length(); ++i) {
|
|
|
|
expect(f.apply(data, i) == data.charAt(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{ Function<java.util.List<String>, Iterator<String>> f = java.util.List<String>::iterator;
|
|
|
|
Iterator<String> iter = f.apply(Arrays.asList("1", "22", "333"));
|
|
|
|
expect(iter.next() == "1");
|
|
|
|
expect(iter.next() == "22");
|
|
|
|
expect(iter.next() == "333");
|
|
|
|
expect(! iter.hasNext());
|
|
|
|
}
|
|
|
|
|
|
|
|
{ BiFunction<GetLong, Long, Long> f = GetLong::get;
|
|
|
|
expect(f.apply(new LongHolder(), 20L) == 20L);
|
|
|
|
}
|
|
|
|
|
|
|
|
{ BiFunction<GetDouble, Double, Double> f = GetDouble::get;
|
|
|
|
expect(f.apply(new DoubleHolder(), 20d) == 20d);
|
|
|
|
}
|
|
|
|
|
2017-01-19 17:27:08 +00:00
|
|
|
// This abort()s in machine.cpp
|
|
|
|
// { Foo s = (Foo & Marker) this::requiresBridge;
|
|
|
|
// s.someFunction(1, 2, "");
|
|
|
|
// }
|
|
|
|
|
2017-07-10 16:01:56 +00:00
|
|
|
{ UnboxedSerializable s = InvokeDynamic::addBoxed;
|
|
|
|
expect(s.add(1, 2) == 3);
|
|
|
|
}
|
2017-01-19 17:27:08 +00:00
|
|
|
|
2017-07-10 16:01:56 +00:00
|
|
|
{ Unboxed s = InvokeDynamic::addBoxed;
|
|
|
|
expect(s.add(1, 2) == 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
{ Supplier<java.util.List<String>> s = java.util.ArrayList<String>::new;
|
|
|
|
java.util.List<String> list = s.get();
|
|
|
|
}
|
2015-05-04 02:57:38 +00:00
|
|
|
}
|
|
|
|
}
|