Inference
jshell> var l=List.of(1,2,3)
l ==> [1, 2, 3]
| created variable l : List<Integer>
jshell> var s=l.stream()
s ==> java.util.stream.ReferencePipeline$Head@31a5c39e
| created variable s : java.util.stream.Stream<Integer>
display elements
jshell> Consumer<Object> print = System.out::println
print ==> $Lambda$14/346861221@7e0b0338
| created variable print : Consumer<Object>
jshell> s.forEach(print)
1
2
3
Encouraging intermediate variables
jshell> var si=l.stream().
...> filter(s->s.length() > 3).
...> mapTo
mapToDouble( mapToInt( mapToLong(
...> mapToInt(String::length)
si ==> java.util.stream.ReferencePipeline$4@65e2dbf3
| replaced variable si : IntStream
| update overwrote variable si : Stream<String>
jshell> var max = si.max()
max ==> OptionalInt[8]
| created variable max : OptionalInt
Example 2
var path = Paths.get(".")
var files=Files.list(path)
var names=files.map(f->f.getFileName())
names.forEach(prn)
var with name var
jshell> var var ="aaa"
var ==> "aaa"
| created variable var : String
var in if
var names = List.of("Luke", "Eva");
for (var name : names) {
System.out.println(name);
}
Inference of most specific type
jshell> var l=new LinkedList<String>()
l ==> []
| replaced variable l : LinkedList<String>
| update overwrote variable l : List<Serializable&Comparable<? extends Serializable&Comparable<?>>>
jshell> l = new ArrayList<String>()
| Error:
| incompatible types: java.util.ArrayList<java.lang.String> cannot be converted to java.util.LinkedList<java.lang.String>
| l = new ArrayList<String>()
| ^---------------------^
jshell> l = new ArrayList<>()
| Error:
| incompatible types: cannot infer type arguments for java.util.ArrayList<>
| reason: no instance(s) of type variable(s) E exist so that java.util.ArrayList<E> conforms to java.util.LinkedList<java.lang.String>
| l = new ArrayList<>()
| ^---------^
jshell> l = new LinkedList<>()
l ==> []
| assigned to l : LinkedList<String>
Comparison
//old way
URL codefx = new URL("http://codefx.org")
URLConnection connection = codefx.openConnection();
Reader reader = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
//new way
var codefx = new URL("http://codefx.org");
var connection = codefx.openConnection();
var reader = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
//copied from https://blog.codefx.org/java/java-10-var-type-inference/
// with explicit types
No no = new No();
AmountIncrease<BigDecimal> more = new BigDecimalAmountIncrease();
HorizontalConnection<LinePosition, LinePosition> jumping =
new HorizontalLinePositionConnection();
Variable variable = new Constant(5);
List<String> names = List.of("Max", "Maria");
// with inferred types
var no = new No();
var more = new BigDecimalAmountIncrease();
var jumping = new HorizontalLinePositionConnection();
var variable = new Constant(5);
var names = List.of("Max", "Maria");
Not Javascript
jshell> var x = 1
x ==> 1
| created variable x : int
jshell> x=2
x ==> 2
| assigned to x : int
jshell> x="aa"
| Error:
| incompatible types: java.lang.String cannot be converted to int
| x="aa"
| ^--^
jshell> var o = "aaaa"
o ==> "aaaa"
| created variable o : String
jshell> o.getClass().getName()
$43 ==> "java.lang.String"
| created scratch variable $43 : String
Not Allowed
//no initializers
jshell> var a
| Error:
| cannot infer type for local variable a
| (cannot use 'var' on variable without initializer)
| var a;
| ^----^
//no lambdas
jshell> var f=(Integer i) -> i+1
| Error:
| cannot infer type for local variable f
| (lambda expression needs an explicit target-type)
| var f=(Integer i) -> i+1;
| ^-----------------------^
//no null
jshell> var n = null
| Error:
| cannot infer type for local variable n
| (variable initializer is 'null')
| var n = null;
| ^-----------^
//only local
class MyClass{
private var s="aaa";
}
//no method parameters
void greeting(var name) {
System.out.println("Hello, my name is " + name);
}
Not obvious cases
//upper bounds
jshell> var l = List.of(1,"aaa")
l ==> [1, aaa]
| modified variable l : List<Serializable&Comparable<? extends Serializable&Comparable<?>>>
| update overwrote variable l : List<String>
//anonymous classes
jshell> var c = new Serializable(){}
c ==> $1@1c3a4799
| created variable c : <anonymous class implementing Serializable>
jshell> c.getClass()
$34 ==> class $1
| created scratch variable $34 : Class<? extends $1>
Request Builder
/env -add-modules jdk.incubator.httpclient
import jdk.incubator.http.*
var client= HttpClient.newHttpClient()
var request = HttpRequest.newBuilder().uri(URI.create("http://openjdk.java.net/")).build()
var sending=client.sendAsync(request, HttpResponse.BodyHandler.asString())
sending.thenApply(HttpResponse::body).thenAccept(System.out::println).join()
Building client
jshell> var client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_2).followRedirects(HttpClient.Redirect.ALWAYS).build()
client ==> jdk.incubator.http.HttpClientImpl@971d0d8
Building request
var req=HttpRequest.newBuilder().uri(uri).timeout(java.time.Duration.ofMinutes(1))
synchronous request
jshell> var response=client.send(req.build(),HttpResponse.BodyHandler.asString())
jshell> response.statusCode()
$13 ==> 200
jshell> response.body()
asynchronous request
jshell> var responseFuture=client.sendAsync(req.build(),HttpResponse.BodyHandler.asString())
responseFuture ==> jdk.incubator.http.internal.common.MinimalFuture@341b80b2[Not completed] (id=33)
jshell> Function<HttpResponse,HttpResponse> display=resp->{
...> System.out.println(response.statusCode()); return response;}
responseFuture.thenApply(display).thenApply(HttpResponse::body).thenAccept(System.out::println)
Links
Intersection Types
@SuppressWarnings("unchecked")
private static <T extends Closeable & Iterator<String>>
T createCloseableIterator(boolean empty) {
if (empty)
return (T) new Empty();
else
return (T) new Scanner(System.in);
}
var elements = createCloseableIterator(empty);