Upload
marcelo-de-castro
View
896
Download
4
Embed Size (px)
Citation preview
Código “invocado” com java.lang.invoke
JustJava 2012
Marcelo de Castro [email protected]
@mcastroinfo
Alexandre Castro [email protected]
@CastroAlexandre
Código “invocado com
java.lang.invoke
• Pacote java.lang.invoke
– JSR 292
• Show me the code!
– Exemplos de uso da API
– Comparativo do desempenho entre Chamadas
• Diretas
• Reflection (java.lang.Method)
• MethodHandle (java.lang.invoke)
• CallSite (java.lang.invoke)
java.lang.invoke
010101010101111100000000010100111000111000111000000011110101010101100011101001001010000101001010101011010110111
java.lang.invoke
• CallSite
– ConstantCallSite
– MutableCallSite
– VolatileCallSite
• MethodHandle
• MethodHandleProxies
• MethodHandles
• MethodHandles.Lookup
• MethodType
• SwitchPoint
• WrongMethodTypeException
java.lang.invoke
• CallSite
– ConstantCallSite
– MutableCallSite
– VolatileCallSite
• MethodHandle
• MethodHandleProxies
• MethodHandles
• MethodHandles.Lookup
• MethodType
• SwitchPoint
• WrongMethodTypeException
<abstract> CallSite
• Um CallSite detém um MethodHandle, que é chamado de alvo (target)
• Uma instrução invokedynamic vinculada a um CallSite delega todas as chamadas ao alvo atual.
• Implementações – ConstantCallSite
– MutableCallSite
– VolatileCallSite
Implementações de CallSite
• ConstantCallSite – Não permite a alteração do MethodHandle alvo
(target) – Toda chamada ao método setTarget lança uma UnsupportedOperationException
• MutableCallSite
– Permite a alteração do MethodHandle alvo ("target“)
• VolatileCallSite
– O MethodHandle alvo ("target") funciona como uma variável volátil (volatile*)
MethodHandle
• Pode referenciar
– um método (de classe ou instância)
– um campo (de classe ou instância)
– um construtor
– outro MethodHandle
• Pode opcionalmente sofrer alterações dos argumentos e valores de retorno (ver MethodHandles)
MethodHandleProxies
• Classe que contém métodos estáticos que criam instâncias de MethodHandle capazes de trabalhar com outros tipos de elementos, como interfaces por exemplo
MethodHandles
• Provê apenas métodos estáticos que possibilitam manipular uma referência de MethodHandle
– Criando
– Combinando
– Transformando
– Convertendo
MethodHandle.Lookup
• fábrica para criação de MethodHandle quando a criação requer verificação da restrição de acesso.
• A restrição de acesso (visibilidade) do MethodHandle é realizada neste momento e não quando o MethodHandle é chamado.
MethodType
• Classe final que representa o tipo de retorno e os argumentos (se houver) do métodos (colocar campos etc) que será manipulado por um MethodHandle
• Todas instâncias de MethodType são imutáveis
• Possui construtor privado, objetos são obtidos por métodos
SwitchPoint
• Um SwitchPoint é um objeto que pode publicar transições de estado para outras threads
• Transições de estado: válido → inválido
• Pode combinar um par de MethodHandle (target, fallback com o mesmo MethodType) em um novo MethodHandle “delegador”
• O estado do SwitchPoint determina qual vai receber a delegação – Válido => target
– Inválido => fallback
WrongMethodTypeException
• RuntimeException
• Indica que o ocorreu a tentativa de construção, combinação, ou chamada de um MethodHandle por meio de tipo errados (MethodType), o que ocorrer primeiro
SHOW ME THE CODE!
010101010101111100000000010100111000111000111000000011110101010101100011101001001010000101001010101011010110111
MethodTypeExample.java
MethodType mtStrRetStrArg =
MethodType.methodType(String.class, String.class);
MethodType mtIntRet =
MethodType.methodType(int.class);
MethodType mtStrRetIntArg =
MethodType.methodType(String.class, int.class);
MethodHandlerExample.java
MethodHandle mhConcat =
MethodHandles.lookup().findVirtual
(String.class,"concat", mtStrReturnStrArg);
String retConcat = (String) mhConcat.invokeExact("Ja", "va“);
System.out.println(retConcat);// Java
MethodHandle mhLength =
MethodHandles.lookup().findVirtual
(String.class, "length", mtIntReturn);
int retLength = (int) mhLength.invokeExact("Java“);
System.out.println(retLength);// 4
MethodHandle mhToBinaryString =
MethodHandles.lookup().findStatic
(Integer.class, "toBinaryString", stStrRetIntArg);
String bStr = (String) mhToBinaryString.invokeExact(10);
System.out.println(bStr);// 1010
DropArgumentsExample.java
MethodHandle mhConcat = getConcatMethodHandle();
String str0 =(String)mhConcat.invokeExact("x", "y");
//xy
MethodHandle mhIgnoreArg0 = MethodHandles.
dropArguments (mhConcat, 0, String.class);
String str1 =
(String)mhIgnoreArg0.invokeExact("x", "y", "z");
//yz
MethodHandle mhIgnoreArg1And2 MethodHandles.
dropArguments(mhConcat, 1, int.class, String.class);
String str2 =
(String) mhIgnoreArg1And2.invokeExact("x", 1, "y", "z");
//xz
MethodHandle mhReplace = getReplaceMethodHandle();
String str0 = (String)
mhReplace.invokeExact("JustJava", 'a','4'));
// JustJ4v4
MethodHandle mhInsertArg1 = MethodHandles.
insertArguments(mhReplace, 1,'J');
String str1 = (String)
mhInsertArg1.invokeExact("JustJava", 'X'));
//XustXava
MethodHandle mhInserArg2 = MethodHandles.
insertArguments(mhInsertArg1, 0, "JustJava");
String str1 = (String)
mhInserArg2.invokeExact( 'T'));
//TustTava
InsertArgumentsExample.java
MethodHandle mhReplace = getReplaceMethodHandle();
String str0 = (String)
mhReplace.invokeExact("JustJava", 'a','4'));
// JustJ4v4
MethodHandle mhInsertArg1 = MethodHandles.
insertArguments(mhReplace, 1,'J');
String str1 = (String)
mhInsertArg1.invokeExact("JustJava", 'X'));
//XustXava
MethodHandle mhInserArg2 = MethodHandles.
insertArguments(mhInsertArg1, 0, "JustJava");
String str1 = (String)
mhInserArg2.invokeExact( 'T'));
//TustTava
InsertArgumentsExample.java
‘J’,
MethodHandle mhReplace = getReplaceMethodHandle();
String str0 = (String)
mhReplace.invokeExact("JustJava", 'a','4'));
// JustJ4v4
MethodHandle mhInsertArg1 = MethodHandles.
insertArguments(mhReplace, 1,'J');
String str1 = (String)
mhInsertArg1.invokeExact("JustJava", 'X'));
//XustXava
MethodHandle mhInserArg2 = MethodHandles.
insertArguments(mhInsertArg1, 0, "JustJava");
String str1 = (String)
mhInserArg2.invokeExact( 'T'));
//TustTava
InsertArgumentsExample.java
‘JustJava’, ‘J’,
PermuteArgumentsExample.java
MethodHandle mhRePlace = getReplaceMethodHandle();
String str0 =
(String) mhRePlace.invokeExact("JustJava", 'a', 'u‘);
//JustJuvu
MethodHandle mhPlaceRe = MethodHandles.
permuteArguments(mhRePlace, mtNovo, 0, 2, 1);
String str0 = (String)
mhPlaceRe.invokeExact("JustJava", 'a', 'u'));
//JastJava
FilterReturnValueExample.java
/*O argumento do filtro (se houver)
deve ser o mesmo do tipo de retorno do alvo */
MethodHandle mhAdapter =
MethodHandles.
filterReturnValue(mhConcatTarget, mhLengthFilter);
mhAdapter.invoke(“Just", “Java")//8
/* mhConcatTarget.type()=> (String, String)String
* mhLengthFilter.type()=> (String)int
* mhAdapter.type(); => (String, String)int
*/
CallSiteExample.java
CallSite callSite = new MutableCallSite(mtStrReturn);
MethodHandle mhDynamic = callSite.dynamicInvoker();
callSite.setTarget(
MethodHandles.constant(String.class, “Just"));
String ret1 = (String) mhDynamic.invokeExact();//Just
MethodHandle worker =
MethodHandles.filterReturnValue(mhDynamic, mhUpper);
callSite.setTarget(
MethodHandles.constant(String.class, “Java"));
String ret2 = (String) worker.invokeExact();//JAVA
SwitchPointExample.java
SwitchPoint switchPoint = new SwitchPoint();
MethodHandle mhTarget = getConcatMethodHandle();
MethodHandle mhFallback = MethodHandles.
permuteArguments(mhTarget, mhTarget.type(), 1, 0);
MethodHandle mhDelegator =
switchPoint.guardWithTest(mhTarget, mhFallback);
String str=(String)mhDelegator.invoke("Just", "Java"));
//JustJava
SwitchPoint.
invalidateAll(new SwitchPoint[]{switchPoint});
String str=(String)mhDelegator.invoke("Just", "Java"));
//JavaJust
inválido válido
ReflectionToInvokeExample
Method methodConcat =
String.class.
getDeclaredMethod("concat", String.class);
MethodHandle mhConcat =
MethodHandles.lookup().unreflect(methodConcat);
System.out.println(mhConcat.invoke("Just", "Java"));
//JustJava
br.eti.castro.example.
invoke.accesscontrol
• ClassToAcess
– publicField, protectedField, packegeField, privateField
– public void publicMethod(){}
– protected void protectedMethod(){}
– void packageMethod(){}
– private void privateMethod(){}
• FieldAcessTest
– Acessando e atribuindo valores
• MethodAcessTest
– Invocando os métodos
br.eti.castro.example.
invoke.performance
• Increaser
– public int increase(int i){return i++;}
• ExampleDirectlyInvoke
– int r = inc.increase(i);
• ExampleReflect
– int r = (int) method.invoke(object, param);
• ExampleInvoke
– int r = (int) methodHandle.invokeExact(param);
• ExampleInvokeCallSite
– int r = (int) mhBinded.invokeExact(param);
Referências
• JSR 292: Supporting Dynamically Typed Languages on the JavaTM Platform http://jcp.org/en/jsr/detail?id=292
• Javadoc SE 7 http://docs.oracle.com/javase/7/docs/api/
• Method Handles and Beyond… John R. Rose, Da Vinci Machine Project, JSR 292 Lead http://www.parleys.com/#id=2631&st=5 @JVMLanguageSummit2011
• MethodHandle implemention tips and tricks Dan Heidinga http://bit.ly/KtZYqb @JVMLanguageSummit2011
• Java 7: Soporte a lenguajes dinámicos Roberto Montero Miguel
Marcelo de Castro [email protected]
@mcastroinfo
Alexandre Castro [email protected]
@CastroAlexandre
OBRIGADO!