Idioma

MethodHandle.AsVarargsCollector(Class) Método

Definição

Torna um <>adaptador em variable arity</em> que é capaz de aceitar qualquer número de argumentos posicionais à direita e recolhê-los em um argumento de matriz.

[Android.Runtime.Register("asVarargsCollector", "(Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;", "GetAsVarargsCollector_Ljava_lang_Class_Handler", ApiSince=26)]
public virtual Java.Lang.Invoke.MethodHandle? AsVarargsCollector(Java.Lang.Class? arrayType);
[<Android.Runtime.Register("asVarargsCollector", "(Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;", "GetAsVarargsCollector_Ljava_lang_Class_Handler", ApiSince=26)>]
abstract member AsVarargsCollector : Java.Lang.Class -> Java.Lang.Invoke.MethodHandle
override this.AsVarargsCollector : Java.Lang.Class -> Java.Lang.Invoke.MethodHandle

Parâmetros

arrayType
Class

frequentemente Object[], o tipo do argumento de matriz que coletará os argumentos

Retornos

um novo identificador de método que pode coletar qualquer número de argumentos à direita em uma matriz, antes de chamar o identificador de método original

Atributos

Comentários

Torna um <>adaptador em variable arity</em> que é capaz de aceitar qualquer número de argumentos posicionais à direita e recolhê-los em um argumento de matriz.

O tipo e o comportamento do adaptador serão os mesmos que o tipo e o comportamento do destino, exceto pelo fato de que determinadas invoke solicitações asType podem levar à coleta de argumentos posicionais à direita no parâmetro à direita do destino. Além disso, o último tipo de parâmetro MethodType#lastParameterType do adaptador será arrayType, mesmo que o destino tenha um tipo de último parâmetro diferente.

Essa transformação poderá ser retornada this se o identificador do método já tiver aridade variável e seu tipo de parâmetro à direita for idêntico a arrayType.

Quando chamado com #invokeExact invokeExact, o adaptador invoca o destino sem alterações de argumento. (<em>Observação:</em> Esse comportamento é diferente de um coletor de aridade fixo #asCollector, pois aceita uma matriz inteira de comprimento indeterminado, em vez de um número fixo de argumentos.)

Quando chamado com simples, inexact #invoke invoke, se o tipo de chamador for o mesmo que o adaptador, o adaptador invocará o destino como com invokeExact. (Esse é o comportamento normal para invoke quando os tipos correspondem.)

Caso contrário, se o chamador e a aridade do adaptador forem os mesmos e o tipo de parâmetro à direita do chamador for um tipo de referência idêntico ou atribuível ao tipo de parâmetro à direita do adaptador, os argumentos e os valores retornados serão convertidos de forma emparelhada, como se estivesse #asType asType em um identificador de método arity fixo.

Caso contrário, as aridades diferem ou o tipo de parâmetro à direita do adaptador não é atribuível do tipo de chamador correspondente. Nesse caso, o adaptador substitui todos os argumentos à direita da posição original do argumento à direita em diante, por uma nova matriz de tipo arrayType, cujos elementos compõem (em ordem) os argumentos substituídos.

O tipo de chamador deve fornecer argumentos mínimos e do tipo correto para atender ao requisito do destino para argumentos posicionais antes do argumento de matriz à direita. Portanto, o chamador deve fornecer, no mínimo, N-1 argumentos, onde N está a aridade do destino. Além disso, deve haver conversões dos argumentos de entrada para os argumentos do destino. Assim como acontece com outros usos de simples invoke, se esses requisitos básicos não forem atendidos, um WrongMethodTypeException pode ser gerado.

Em todos os casos, o que o destino eventualmente retorna é retornado inalterado pelo adaptador.

No caso final, é exatamente como se o identificador do método de destino tivesse sido temporariamente adaptado com um coletor de arity #asCollector fixo para a aridade exigida pelo tipo de chamador. (Como acontece com asCollector, se o comprimento da matriz for zero, uma constante compartilhada poderá ser usada em vez de uma nova matriz. Se a chamada implícita gerar asCollector um IllegalArgumentException ou WrongMethodTypeException, a chamada para o adaptador de aridade variável deverá gerar WrongMethodTypeException.)

O comportamento também é especializado para adaptadores de #asType asType aridade variável, para manter o invariável de que simples, inexact invoke é sempre equivalente a uma asType chamada para ajustar o tipo de destino, seguido por invokeExact. Portanto, um adaptador de aridade variável responde a uma solicitação asType criando um coletor de arity fixo, se e somente se o adaptador e o tipo solicitado forem diferentes no tipo de argumento arity ou trailing. O coletor de arity fixo resultante tem seu tipo ajustado (se necessário) para o tipo solicitado por conversão par, como se fosse por outra aplicação de asType.

Quando um identificador de método é obtido executando uma ldc instrução de uma CONSTANT_MethodHandle constante e o método de destino é marcado como um método de aridade variável (com o bit 0x0080modificador), o identificador do método aceitará várias aridades, como se a constante de identificador de método tivesse sido criada por meio de uma chamada para asVarargsCollector.

Para criar um adaptador de coleta que coleta um número predeterminado de argumentos e cujo tipo reflete esse número predeterminado, use #asCollector asCollector em vez disso.

Nenhuma transformação de identificador de método produz novos identificadores de método com aridade variável, a menos que estejam documentadas como fazendo isso. Portanto, além de withVarargstodos os métodos MethodHandleasVarargsCollector e MethodHandles retornarão um identificador de método com aridade fixa, exceto nos casos em que eles são especificados para retornar seu operando original (por exemplo, asType do próprio tipo do identificador do método).

Chamar asVarargsCollector um identificador de método que já é de aridade variável produzirá um identificador de método com o mesmo tipo e comportamento. Ele pode (ou não) retornar o identificador do método arity de variável original.

Aqui está um exemplo de um identificador de método de aridade variável de criação de lista: <blockquote>

{@code
            MethodHandle deepToString = publicLookup()
              .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
            MethodHandle ts1 = deepToString.asVarargsCollector(Object[].class);
            assertEquals("[won]",   (String) ts1.invokeExact(    new Object[]{"won"}));
            assertEquals("[won]",   (String) ts1.invoke(         new Object[]{"won"}));
            assertEquals("[won]",   (String) ts1.invoke(                      "won" ));
            assertEquals("[[won]]", (String) ts1.invoke((Object) new Object[]{"won"}));
            // findStatic of Arrays.asList(...) produces a variable arity method handle:
            MethodHandle asList = publicLookup()
              .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class));
            assertEquals(methodType(List.class, Object[].class), asList.type());
            assert(asList.isVarargsCollector());
            assertEquals("[]", asList.invoke().toString());
            assertEquals("[1]", asList.invoke(1).toString());
            assertEquals("[two, too]", asList.invoke("two", "too").toString());
            String[] argv = { "three", "thee", "tee" };
            assertEquals("[three, thee, tee]", asList.invoke(argv).toString());
            assertEquals("[three, thee, tee]", asList.invoke((Object[])argv).toString());
            List ls = (List) asList.invoke((Object)argv);
            assertEquals(1, ls.size());
            assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
            }

</blockquote>

<em>Discussão:</em> Essas regras são projetadas como uma variação de tipo dinâmico das regras de Java para métodos de aridade variável. Em ambos os casos, os chamadores para um método de aridade variável ou identificador de método podem passar zero ou mais argumentos posicionais ou então passar matrizes pré-coletadas de qualquer comprimento. Os usuários devem estar cientes da função especial do argumento final e do efeito de uma correspondência de tipo nesse argumento final, que determina se um único argumento à direita é ou não interpretado como uma matriz inteira ou um único elemento de uma matriz a ser coletado. Observe que o tipo dinâmico do argumento à direita não tem efeito sobre essa decisão, apenas uma comparação entre o descritor de tipo simbólico do site de chamada e o descritor de tipo do identificador de método.)

Documentação Java para java.lang.invoke.MethodHandle.asVarargsCollector(java.lang.Class<?>).

Partes desta página são modificações baseadas no trabalho criado e compartilhado pelo Android Open Source Project e usadas de acordo com os termos descritos na Licença de Atribuição Creative Commons 2.5.

Aplica-se a