mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 02:54:35 +02:00
8080641: JEP-JDK-8042880 : Implement new tests on Project Coin
A set of tests using t-w-r as variable in different positive and negative constructions Reviewed-by: abuckley, darcy, jlahoda, sadayapalam
This commit is contained in:
parent
e539e10105
commit
02d2bd56f3
17 changed files with 361 additions and 14 deletions
|
@ -9,12 +9,22 @@ import java.io.*;
|
||||||
|
|
||||||
class T7022711 {
|
class T7022711 {
|
||||||
public static void main (String args[]) throws Exception {
|
public static void main (String args[]) throws Exception {
|
||||||
|
// declared resource
|
||||||
try (DataInputStream is = new DataInputStream(new FileInputStream("x"))) {
|
try (DataInputStream is = new DataInputStream(new FileInputStream("x"))) {
|
||||||
while (true) {
|
while (true) {
|
||||||
is.getChar(); // method not found
|
is.getChar(); // method not found
|
||||||
}
|
}
|
||||||
} catch (EOFException e) {
|
} catch (EOFException e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resource as variable
|
||||||
|
DataInputStream is = new DataInputStream(new FileInputStream("x"));
|
||||||
|
try (is) {
|
||||||
|
while (true) {
|
||||||
|
is.getChar(); // method not found
|
||||||
|
}
|
||||||
|
} catch (EOFException e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
T7022711.java:14:19: compiler.err.cant.resolve.location.args: kindname.method, getChar, , , (compiler.misc.location.1: kindname.variable, is, java.io.DataInputStream)
|
T7022711.java:15:19: compiler.err.cant.resolve.location.args: kindname.method, getChar, , , (compiler.misc.location.1: kindname.variable, is, java.io.DataInputStream)
|
||||||
1 error
|
T7022711.java:24:19: compiler.err.cant.resolve.location.args: kindname.method, getChar, , , (compiler.misc.location.1: kindname.variable, is, java.io.DataInputStream)
|
||||||
|
2 errors
|
||||||
|
|
|
@ -33,8 +33,15 @@ import java.io.OutputStream;
|
||||||
|
|
||||||
public class T7032633 {
|
public class T7032633 {
|
||||||
void test() throws IOException {
|
void test() throws IOException {
|
||||||
|
// declared resource
|
||||||
try (OutputStream out = System.out) {
|
try (OutputStream out = System.out) {
|
||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resource as variable
|
||||||
|
OutputStream out = System.out;
|
||||||
|
try (out) {
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* @test /nodynamiccopyright/
|
||||||
|
* @bug 7196163
|
||||||
|
* @summary Twr with resource variables as lambda expressions and method references
|
||||||
|
* @compile/fail/ref=TwrAndLambda.out -XDrawDiagnostics TwrAndLambda.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TwrAndLambda {
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
|
||||||
|
// Lambda expression
|
||||||
|
AutoCloseable v1 = () -> {};
|
||||||
|
// Static method reference
|
||||||
|
AutoCloseable v2 = TwrAndLambda::close1;
|
||||||
|
// Instance method reference
|
||||||
|
AutoCloseable v3 = new TwrAndLambda()::close2;
|
||||||
|
// Lambda expression which is not AutoCloseable
|
||||||
|
Runnable r1 = () -> {};
|
||||||
|
// Static method reference which is not AutoCloseable
|
||||||
|
Runnable r2 = TwrAndLambda::close1;
|
||||||
|
// Instance method reference which is not AutoCloseable
|
||||||
|
Runnable r3 = new TwrAndLambda()::close2;
|
||||||
|
|
||||||
|
try (v1) {
|
||||||
|
} catch(Exception e) {}
|
||||||
|
try (v2) {
|
||||||
|
} catch(Exception e) {}
|
||||||
|
try (v3) {
|
||||||
|
} catch(Exception e) {}
|
||||||
|
try (r1) {
|
||||||
|
} catch(Exception e) {}
|
||||||
|
try (r2) {
|
||||||
|
} catch(Exception e) {}
|
||||||
|
try (r3) {
|
||||||
|
} catch(Exception e) {}
|
||||||
|
|
||||||
|
// lambda invocation
|
||||||
|
I i = (x) -> { try(x) { } catch (Exception e) { } };
|
||||||
|
i.m(v1);
|
||||||
|
i.m(v2);
|
||||||
|
i.m(v3);
|
||||||
|
i.m(r1);
|
||||||
|
i.m(r2);
|
||||||
|
i.m(r3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static interface I {
|
||||||
|
public void m(AutoCloseable r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close1() { }
|
||||||
|
|
||||||
|
public void close2() { }
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
TwrAndLambda.java:31:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: java.lang.Runnable, java.lang.AutoCloseable))
|
||||||
|
TwrAndLambda.java:33:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: java.lang.Runnable, java.lang.AutoCloseable))
|
||||||
|
TwrAndLambda.java:35:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: java.lang.Runnable, java.lang.AutoCloseable))
|
||||||
|
TwrAndLambda.java:43:10: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.AutoCloseable, java.lang.Runnable, kindname.interface, TwrAndLambda.I, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Runnable, java.lang.AutoCloseable))
|
||||||
|
TwrAndLambda.java:44:10: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.AutoCloseable, java.lang.Runnable, kindname.interface, TwrAndLambda.I, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Runnable, java.lang.AutoCloseable))
|
||||||
|
TwrAndLambda.java:45:10: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.AutoCloseable, java.lang.Runnable, kindname.interface, TwrAndLambda.I, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Runnable, java.lang.AutoCloseable))
|
||||||
|
6 errors
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* @test /nodynamiccopyright/
|
||||||
|
* @bug 7196163
|
||||||
|
* @summary Twr with resource variables of parametrized types
|
||||||
|
* @compile/fail/ref=TwrAndTypeVariables.out -XDrawDiagnostics TwrAndTypeVariables.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TwrAndTypeVariables {
|
||||||
|
|
||||||
|
// positive
|
||||||
|
public static <S extends Readable & AutoCloseable,
|
||||||
|
T extends Appendable & AutoCloseable>
|
||||||
|
void copy(S s, T t) throws Exception {
|
||||||
|
try (s; t;) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// negative
|
||||||
|
public static <S> void copy(S s) throws Exception {
|
||||||
|
try (s) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
TwrAndTypeVariables.java:20:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: S, java.lang.AutoCloseable))
|
||||||
|
1 error
|
|
@ -37,6 +37,49 @@ public class TwrForVariable1 implements AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
assertCloseCount(6);
|
assertCloseCount(6);
|
||||||
|
|
||||||
|
// null test cases
|
||||||
|
TwrForVariable1 n = null;
|
||||||
|
|
||||||
|
try (n) {
|
||||||
|
}
|
||||||
|
try (n) {
|
||||||
|
throw new Exception();
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
assertCloseCount(6);
|
||||||
|
|
||||||
|
// initialization exception
|
||||||
|
TwrForVariable1 i1 = new TwrForVariable1();
|
||||||
|
try (i1; TwrForVariable1 i2 = new TwrForVariable1(true)) {
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
assertCloseCount(7);
|
||||||
|
|
||||||
|
// multiple closures
|
||||||
|
TwrForVariable1 m1 = new TwrForVariable1();
|
||||||
|
try (m1; TwrForVariable1 m2 = m1; TwrForVariable1 m3 = m2;) {
|
||||||
|
}
|
||||||
|
|
||||||
|
assertCloseCount(10);
|
||||||
|
|
||||||
|
// aliasing of variables keeps equality (bugs 6911256 6964740)
|
||||||
|
TwrForVariable1 a1 = new TwrForVariable1();
|
||||||
|
try (a1; TwrForVariable1 a2 = a1;) {
|
||||||
|
if (a2 != a2)
|
||||||
|
throw new RuntimeException("Unexpected inequality.");
|
||||||
|
}
|
||||||
|
|
||||||
|
assertCloseCount(12);
|
||||||
|
|
||||||
|
// anonymous class implementing AutoCloseable as variable in twr
|
||||||
|
AutoCloseable a = new AutoCloseable() {
|
||||||
|
public void close() { };
|
||||||
|
};
|
||||||
|
try (a) {
|
||||||
|
} catch (Exception e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void assertCloseCount(int expectedCloseCount) {
|
static void assertCloseCount(int expectedCloseCount) {
|
||||||
|
@ -66,4 +109,13 @@ public class TwrForVariable1 implements AutoCloseable {
|
||||||
closeCount++;
|
closeCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TwrForVariable1(boolean throwException) {
|
||||||
|
if (throwException)
|
||||||
|
throw new RuntimeException("Initialization exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
public TwrForVariable1() {
|
||||||
|
this(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ public class TwrForVariable2 implements AutoCloseable {
|
||||||
public static void main(String... args) {
|
public static void main(String... args) {
|
||||||
TwrForVariable2 v = new TwrForVariable2();
|
TwrForVariable2 v = new TwrForVariable2();
|
||||||
TwrForVariable3[] v2 = new TwrForVariable3[1];
|
TwrForVariable3[] v2 = new TwrForVariable3[1];
|
||||||
|
TwrForVariable3[][] v3 = new TwrForVariable3[1][1];
|
||||||
|
|
||||||
try (final v) {
|
try (final v) {
|
||||||
fail("no modifiers before variables");
|
fail("no modifiers before variables");
|
||||||
|
@ -24,9 +25,15 @@ public class TwrForVariable2 implements AutoCloseable {
|
||||||
try (v2[0]) {
|
try (v2[0]) {
|
||||||
fail("array access not allowed");
|
fail("array access not allowed");
|
||||||
}
|
}
|
||||||
|
try (v3[0][0]) {
|
||||||
|
fail("array access not allowed");
|
||||||
|
}
|
||||||
try (args.length == 0 ? v : v) {
|
try (args.length == 0 ? v : v) {
|
||||||
fail("general expressions not allowed");
|
fail("general expressions not allowed");
|
||||||
}
|
}
|
||||||
|
try ((TwrForVariable2)null) {
|
||||||
|
fail("null as variable is not allowed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fail(String reason) {
|
static void fail(String reason) {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
TwrForVariable2.java:12:21: compiler.err.expected: token.identifier
|
TwrForVariable2.java:13:21: compiler.err.expected: token.identifier
|
||||||
TwrForVariable2.java:15:27: compiler.err.expected: token.identifier
|
TwrForVariable2.java:16:27: compiler.err.expected: token.identifier
|
||||||
TwrForVariable2.java:18:16: compiler.err.illegal.start.of.expr
|
TwrForVariable2.java:19:16: compiler.err.illegal.start.of.expr
|
||||||
TwrForVariable2.java:21:14: compiler.err.try.with.resources.expr.needs.var
|
TwrForVariable2.java:22:14: compiler.err.try.with.resources.expr.needs.var
|
||||||
TwrForVariable2.java:24:16: compiler.err.try.with.resources.expr.needs.var
|
TwrForVariable2.java:25:16: compiler.err.try.with.resources.expr.needs.var
|
||||||
TwrForVariable2.java:27:31: compiler.err.try.with.resources.expr.needs.var
|
TwrForVariable2.java:28:19: compiler.err.try.with.resources.expr.needs.var
|
||||||
6 errors
|
TwrForVariable2.java:31:31: compiler.err.try.with.resources.expr.needs.var
|
||||||
|
TwrForVariable2.java:34:14: compiler.err.try.with.resources.expr.needs.var
|
||||||
|
8 errors
|
||||||
|
|
|
@ -7,9 +7,16 @@ public class TwrForVariable3 implements AutoCloseable {
|
||||||
public static void main(String... args) {
|
public static void main(String... args) {
|
||||||
TwrForVariable3 v1 = new TwrForVariable3();
|
TwrForVariable3 v1 = new TwrForVariable3();
|
||||||
Object v2 = new Object();
|
Object v2 = new Object();
|
||||||
|
Object v3 = new Object() {
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
try (v2) {
|
try (v2) {
|
||||||
fail("no an AutoCloseable");
|
fail("not an AutoCloseable");
|
||||||
|
}
|
||||||
|
try (v3) {
|
||||||
|
fail("not an AutoCloseable although has close() method");
|
||||||
}
|
}
|
||||||
try (java.lang.Object) {
|
try (java.lang.Object) {
|
||||||
fail("not a variable access");
|
fail("not a variable access");
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
TwrForVariable3.java:11:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.AutoCloseable))
|
TwrForVariable3.java:15:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.AutoCloseable))
|
||||||
TwrForVariable3.java:14:18: compiler.err.cant.resolve.location: kindname.class, lang, , , (compiler.misc.location: kindname.package, java, null)
|
TwrForVariable3.java:18:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.AutoCloseable))
|
||||||
TwrForVariable3.java:17:14: compiler.err.cant.resolve.location: kindname.variable, java, , , (compiler.misc.location: kindname.class, TwrForVariable3, null)
|
TwrForVariable3.java:21:18: compiler.err.cant.resolve.location: kindname.class, lang, , , (compiler.misc.location: kindname.package, java, null)
|
||||||
3 errors
|
TwrForVariable3.java:24:14: compiler.err.cant.resolve.location: kindname.variable, java, , , (compiler.misc.location: kindname.class, TwrForVariable3, null)
|
||||||
|
4 errors
|
||||||
|
|
81
langtools/test/tools/javac/TryWithResources/TwrVarKinds.java
Normal file
81
langtools/test/tools/javac/TryWithResources/TwrVarKinds.java
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* @test /nodynamiccopyright/
|
||||||
|
* @bug 7196163
|
||||||
|
* @summary Twr with different kinds of variables: local, instance, class, array component, parameter
|
||||||
|
* @compile/fail/ref=TwrVarKinds.out -XDrawDiagnostics TwrVarKinds.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TwrVarKinds implements AutoCloseable {
|
||||||
|
|
||||||
|
final static TwrVarKinds r1 = new TwrVarKinds();
|
||||||
|
final TwrVarKinds r2 = new TwrVarKinds();
|
||||||
|
static TwrVarKinds r3 = new TwrVarKinds();
|
||||||
|
TwrVarKinds r4 = new TwrVarKinds();
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
|
||||||
|
TwrVarKinds r5 = new TwrVarKinds();
|
||||||
|
|
||||||
|
/* static final field - ok */
|
||||||
|
try (r1) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* non-static final field - ok */
|
||||||
|
try (r1.r2) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static non-final field - wrong */
|
||||||
|
try (r3) {
|
||||||
|
fail("Static non-final field is not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* non-static non-final field - wrong */
|
||||||
|
try (r1.r4) {
|
||||||
|
fail("Non-static non-final field is not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* local variable - covered by TwrForVariable1 test */
|
||||||
|
|
||||||
|
/* array components - covered by TwrForVariable2 test */
|
||||||
|
|
||||||
|
/* method parameter - ok */
|
||||||
|
method(r5);
|
||||||
|
|
||||||
|
/* constructor parameter - ok */
|
||||||
|
TwrVarKinds r6 = new TwrVarKinds(r5);
|
||||||
|
|
||||||
|
/* lambda parameter - covered by TwrAndLambda */
|
||||||
|
|
||||||
|
/* exception parameter - ok */
|
||||||
|
try {
|
||||||
|
throw new ResourceException();
|
||||||
|
} catch (ResourceException e) {
|
||||||
|
try (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TwrVarKinds() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TwrVarKinds(TwrVarKinds r) {
|
||||||
|
try (r) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void method(TwrVarKinds r) {
|
||||||
|
/* parameter */
|
||||||
|
try (r) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fail(String reason) {
|
||||||
|
throw new RuntimeException(reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {}
|
||||||
|
|
||||||
|
static class ResourceException extends Exception implements AutoCloseable {
|
||||||
|
public void close() {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
TwrVarKinds.java:28:14: compiler.err.try.with.resources.expr.effectively.final.var: r3
|
||||||
|
TwrVarKinds.java:33:16: compiler.err.try.with.resources.expr.effectively.final.var: r4
|
||||||
|
2 errors
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* @test /nodynamiccopyright/
|
||||||
|
* @bug 7196163
|
||||||
|
* @summary Variable redeclaration inside twr block
|
||||||
|
* @compile/fail/ref=TwrVarRedeclaration.out -XDrawDiagnostics TwrVarRedeclaration.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TwrVarRedeclaration implements AutoCloseable {
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
TwrVarRedeclaration r = new TwrVarRedeclaration();
|
||||||
|
|
||||||
|
try (r) {
|
||||||
|
TwrVarRedeclaration r = new TwrVarRedeclaration();
|
||||||
|
}
|
||||||
|
|
||||||
|
try (r) {
|
||||||
|
Object r = new Object();
|
||||||
|
}
|
||||||
|
|
||||||
|
try (r) {
|
||||||
|
} catch (Exception e) {
|
||||||
|
Exception r = new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
TwrVarRedeclaration.java:14:33: compiler.err.already.defined: kindname.variable, r, kindname.method, main(java.lang.String...)
|
||||||
|
TwrVarRedeclaration.java:18:20: compiler.err.already.defined: kindname.variable, r, kindname.method, main(java.lang.String...)
|
||||||
|
TwrVarRedeclaration.java:23:23: compiler.err.already.defined: kindname.variable, r, kindname.method, main(java.lang.String...)
|
||||||
|
3 errors
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8071453
|
||||||
|
* @summary Verify that generics work with private method in interface
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class PrivateGenerics {
|
||||||
|
|
||||||
|
interface I<T> {
|
||||||
|
private T foo() { return null; };
|
||||||
|
default void m(T t) {
|
||||||
|
T t1 = t;
|
||||||
|
T t2 = foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface J {
|
||||||
|
private <M> M foo() { return null; }
|
||||||
|
default <N> void m(N n) {
|
||||||
|
N n1 = n;
|
||||||
|
N n2 = foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
I<String> i = new I<>() {};
|
||||||
|
i.m("string");
|
||||||
|
String s = i.foo();
|
||||||
|
|
||||||
|
J j = new J() {};
|
||||||
|
j.m("string");
|
||||||
|
s = j.foo();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue