как записать аргумент типа для универсального полиморфного статического метода в jshell?

на простой Java я могу написать

class P {
    static <A> A id (A x) { return x; }
    static int y = P.<Integer>id(8);
    static String bar = P.<String>id("foo");
}

в jshell я могу объявить и использовать id

jshell> <A> A id (A x) { return x; }
|  created method id(A)

jshell> int x = id(8)
x ==> 8

jshell> String y = id("foo")
y ==> "foo"

но я не вижу, как сделать аргумент типа явным.

jshell> String y = <String>id("foo")
|  Error:
|  illegal start of expression
|  String y = <String>id("foo");
|                     ^

Как называется подразумеваемый класс контекста?

Где (часть) спецификации jshell, которая позволила бы мне ответить на этот вопрос? http://openjdk.java.net/jeps/222 просто упоминает "синтетический класс" в "обертке". Не похоже, чтобы это можно было назвать.


person d8d0d65b3f7cf42    schedule 06.06.2016    source источник
comment
Используйте 1_. Что в итоге?   -  person Sotirios Delimanolis    schedule 07.06.2016
comment
попробуйте мой код в jshell, не используя класс P.   -  person d8d0d65b3f7cf42    schedule 07.06.2016
comment
Я понимаю. Вы можете объявлять методы непосредственно в JShell. Должен быть неявный класс.   -  person Sotirios Delimanolis    schedule 07.06.2016
comment
JShell, похоже, создает анонимный класс для каждого объявления члена. Я смог использовать REPL.$JShell$9.<String>id("hey") для вызова метода. Это будет варьироваться в зависимости от каждой декларации. Я не знаю, что они в конечном итоге будут использовать в качестве глобального идентификатора.   -  person Sotirios Delimanolis    schedule 07.06.2016
comment
Хороший! Я думаю, с помощью табуляции.   -  person d8d0d65b3f7cf42    schedule 07.06.2016
comment
Я видел кое-что о классе под названием REPL и пошел оттуда, да.   -  person Sotirios Delimanolis    schedule 07.06.2016
comment
Та же проблема (и решение) применима, если вы хотите использовать ссылку на функцию? Как asList("foo").stream().map(::id)...   -  person Per Huss    schedule 11.06.2016


Ответы (1)


Действительно, ваша ссылка не указывает точную природу (например, имя) синтетического класса, который получает ваши методы. как статические методы.

Я попытался получить класс, в котором выполняется фрагмент, с помощью

jshell> new Exception().printStackTrace()
java.lang.Exception
    at REPL.$JShell$17.do_it$($JShell$17.java:8)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@9-ea/Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@9-ea/NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@9-ea/DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(java.base@9-ea/Method.java:531)
    at jdk.internal.jshell.remote.RemoteAgent.commandLoop(jdk.jshell@9-ea/RemoteAgent.java:124)
    at jdk.internal.jshell.remote.RemoteAgent.main(jdk.jshell@9-ea/RemoteAgent.java:62)

jshell> Thread.currentThread().getStackTrace()[1].toString()
$15 ==> "do_it$(java:18)"

jshell> Thread.currentThread().getStackTrace()[1].getClassName()
$16 ==> ""

но, как видите, информации нет в трассировке стека.

Самый простой способ обойти это — определить ваш метод как статический метод в собственном классе:

jshell> class B { static <A> A id(A x) {return x;} }

Это позволяет вам звонить

jshell> String y = B.<String>id("foo");

и получает желаемый результат.

person Steffen Harbich    schedule 15.06.2016
comment
Вероятно, исходный код jshell: github.com/netroby/jdk9-dev/tree/master/langtools/src/ - person Steffen Harbich; 15.06.2016