Classe de campo
A classe de campo define alguns métodos que podem ser usados para consultar o tipo de campo e definir ou ler o valor de um campo. A combinação desses métodos com o método de membro herdado nos permite descobrir todas as informações sobre a declaração de campo e poder manipular campos de um objeto ou classe específica.
O método getGenerictype retorna uma instância de tipo que representa o tipo de declaração do campo. Para tipos triviais como string ou int, o método retorna o objeto de classe associado a ele, como string.class e int.classo para tipos parametrizados como list <stri ng>, o método retorna uma instância de parametrizeype, por exemplo, para um tipo como t, o método retorna uma instituição de tipo de tipo.
O método Legacy GetType retornará um objeto de classe do tipo de campo. Para tipos triviais, o método se comporta o mesmo que o método getGenerictype. Se o tipo declarado do campo for um tipo parametrizado, o método getType retornará o objeto de classe correspondente para a apagação do tipo parametrizado, ou seja, o objeto de classe do tipo original. Por exemplo, para um objeto declarado como lista <Stri ng>, Gettype retornará a classe Li St.. Se o tipo de campo declarado for uma variável de tipo, o método GetType retornará o objeto de classe correspondente para apagar a variável de tipo. Por exemplo, suponha que haja uma classe Foo <Ding> e, para os campos declarados como T Tipo, a obtenção do YPE retornará o objeto.
objeto de classe. Se o Foo for declarado como foo <estender o número>, então o ype under get retornará o número.class.
Podemos usar o método isenumConstant para consultar se um campo é uma constante enum, ou podemos usar os métodos GET e Set para obter e definir o valor do campo. Esses métodos que aceitam citações de objetos e retornam o valor do objeto ECT têm uma forma comum, bem como alguns formulários mais especializados que podem lidar diretamente com tipos básicos. Todos esses métodos aceitam uma cotação para especificar o objeto a ser operado. Para campos estáticos, essa cotação de objeto será ignorada, para que você também possa defini -lo
Definido como nulo. O método a seguir imprimirá o valor do campo curto de um objeto:
public static void PrintShortfield (objeto o, nome da string) lança NosuchfieldException, ilegalAccessException {campo de campo = o.getclass (). getfield (nome); valor curto = (curto) campo.get (o); System.out.println (valor);O valor de retorno do método get pode ser qualquer objeto referenciado por este campo. Se o campo for um tipo primitivo, o método retornará o tipo apropriado de objeto de classe de wrapper. Para o nosso "campo do tipo Hort, o método GET retorna um objeto do tipo curto contendo o valor do campo e, quando atribuído ao valor da variável local, o valor do objeto será automaticamente não caixa.
O uso do método de conjunto é semelhante. O método de definir o campo curto para o valor fornecido pode ser assim:
public static voi setShortfield (objeto o, nome da string, NV curto) lança NosuchfieldException, campo ilegalAccessException Campo = 0.getClass (). getfield (nome); campo .set (o .nv);
Embora o SET aceite parâmetros do tipo de objeto, podemos passar diretamente um valor curto e embrulhá -lo em um objeto curto com a conversão de embalagem.
No método acima, se o domínio do objeto especificado for inacessível e esse controle de acesso for aplicado, uma exceção ilegalaccessception será lançada; Se o objeto aprovado for diferente do tipo de domínio, uma exceção ilegalArgumentException será lançada; Se o domínio não for estático e a referência de objeto é nula, uma exceção de NullPointerException será lançada; O acesso a um domínio estático pode exigir que a classe seja inicializada; portanto, o método também lançará uma exceção de exceção de exceção.
A classe de campo também possui métodos específicos para obter e definir tipos básicos. Por exemplo, podemos chamar getPrimitive7ype e definir o Primitive7ype no objeto de campo, onde o Primitivo7ype é o nome do tipo básico (capitalizado). O método GET pode ser usado na seguinte declaração:
valor curto = field.getshhort (o);
O método de conjunto pode ser usado na seguinte declaração:
field.setShort (O, NV);
O uso de objetos do tipo wrapper pode ser evitado em declarações declaradas das duas maneiras acima.
A classe de campo implementa a interface AnnoTatedElement, para que também possamos consultar e aplicá -la ao domínio como a Seção 16.2.
Notas sobre.
Com o método descrito acima, podemos usar o objeto de campo como uma maneira de manipular qualquer valor, mas devemos tentar evitá -lo. Como o idioma Java captura erros de programação o maior número possível durante o período de compilação de um programa, quanto menos métodos indiretos, como "objetos IELD", são usados quando escrevemos código, mais erros podem ser evitados antes de compilá -los em código. Além disso, podemos ver que, no código anterior, a fim de saber o que exatamente acontecerá, obviamente gastamos muito mais energia na leitura do código do que ao usar nomes de domínio diretamente na sintaxe comum.
Campos finais
Normalmente, a definição de um campo declarado final fará com que uma ULACALACCESSEXCECTION seja jogada
Exceção, é isso que podemos esperar, porque o valor do campo final nunca mudará. Mas existem alguns casos especiais - por exemplo, na desserialização personalizada (consulte a Seção 20.8.4), faz sentido alterar o valor do campo final, que só podemos alcançar através da reflexão no campo da instância e somente se o setacessível (true) tiver sido chamado no objeto de campo. Observe que não é suficiente para chamar com sucesso o SetAccessible (true) e deve ser chamado de fato.
Essa capacidade é fornecida para contextos altamente especializados e não é de finalidade geral, e a apresentamos para manter apenas a integridade do conteúdo. Se você estiver fora de um contexto específico, como a desserialização personalizada, a alteração do valor do campo final pode levar a consequências inesperadas ou até catastróficas. Fora desses contextos, não há garantia de que as alterações no campo final sejam visíveis. Mesmo nesses contextos, é necessário garantir que o mecanismo de segurança não prejudique a execução do código ao codificar usando essa tecnologia. Alterar o campo final com um valor de variável constante (consulte a Seção 2.2.3) tornará essa alteração invisível, a menos que essa modificação seja alcançada usando a reflexão.
Classe de método
A classe do método e seus métodos herdados da classe membro nos permitem obter as informações completas sobre a declaração do método:
"Tipo público getGenericreturnTypeo: este método retorna um objeto de tipo do tipo de retorno do método de destino. Se o método de destino for declarado retornar vazio, o método retorna void.classo
"Tipo público [] getGeRericParameterTypes (): este método retorna uma matriz de objetos de tipo de todos os tipos de parâmetros do método de destino, que serão armazenados na matriz na ordem de declaração dos parâmetros.
.PUBL IC TYPE [] getGeneri Cacheti Ontypes Q: Este método retorna uma matriz de objetos de tipo de todos os tipos de exceção listados na cláusula de arremesso, que será armazenada na matriz na ordem de declaração de exceção.
Se o método de destino não declarar nenhuma exceção, o método retornará uma matriz vazia.
O Java também fornece métodos getReturntype, getParameterTypes e GetExceptionTypes para retornar Cl como "objeto em vez do objeto de tipo. Assim como ao usar o Field.getType, as variáveis de tipo e tipo parametrizadas são representadas pelo objeto de classe correspondente à sua apaga.
A classe de método implementa o anotação e podemos consultar as anotações aplicadas ao método, conforme discutido na Seção 16.2. Além disso, a classe de método também fornece GetParameterAnnotações para fornecer acesso a anotações aplicadas aos parâmetros do método. O método getParameterAnnotações pode retornar uma matriz de anotação, onde cada elemento da matriz mais externa corresponde aos parâmetros do método; Se um parâmetro não tiver nenhuma anotação, o método retornará uma matriz de anotação do comprimento 0 para este parâmetro. Se o método representado pelo objeto Método for um elemento de anotação, o método getDefaultValue retornará um objeto que representa o valor padrão do elemento; Se o objeto de método em si não for um elemento de anotação ou não tiver um valor padrão, o método retornará a classe NULL. Se o objeto de método fornecido não representa um método genérico, o método retornará uma matriz vazia.
Podemos usar o método iSvarargs para verificar se um objeto de método é um método de índice variável, e o método i sbridge pode ser usado para verificar se é um método de ponte
A maneira mais interessante de usar um objeto de método é se chamar refletivamente:
.public objeto Invoke (objeto On This, objeto ... args) lança ilegalaccescessception, ilegalArgumentException, ArgeTexception sob nvocation: Este método chama o método definido pelo objeto Método On Thishis e usa o valor dos args para definir os parâmetros do método chamado. Para métodos não estáticos, o tipo real de On, isso determina qual implementação do método a ser chamada, enquanto para métodos estáticos, isso será ignorado e geralmente é definido como nulo. O número de valores de args deve ser o mesmo que o número real de parâmetros do método chamado, e os tipos desses valores devem ser atribuídos aos parâmetros do método chamado; Caso contrário, obteremos a exceção de LleGALArgumentException. Observe que o último parâmetro do método de citação variável é uma matriz; portanto, temos que preencher a matriz com as citações "mutáveis" que realmente queremos passar. Se quisermos chamar um método que não temos acesso, o método lançará uma exceção ilegalacalAccessException. Se o método chamado não for o método do objeto ON, o método lançará um llegalargumentExcepti na exceção. Se o On This for NULL e não for estático, o método lançará uma exceção no 1PointerException. Se esse objeto de método representar um método estático e a classe que declara que o método estático ainda está no estado a ser inicializado, o método lançará uma exceção na exceção do NitializerError do trabalhador. Se o método chamado tiver um poder alienígena, a exceção da InvocationTargeTexception será lançada.
Quando usamos o método Invoke, podemos passar diretamente no tipo básico ou podemos usar uma classe de wrapper adequada. O tipo representado pela classe Wrapper deve ser atribuído ao tipo de parâmetro declarado pelo método. Podemos usar longos, flutuadores ou duplos para embrulhar citações do tipo duplo, mas não podemos usar o dobro para embrulhar citações longas ou flutuantes, porque o dobro não pode ser atribuído a Long ou Oat. O método de processamento do objeto retornado pelo método Invoke é o mesmo que o campo. Se o método for declarado vazio, o método Invoke retornará nulo,
Simplificando, quando usamos o Invoke para chamar métodos, só podemos usar parâmetros legais no idioma Java.
Priorizadores com o mesmo tipo e valor. Por exemplo, a seguinte chamada
return str.IndexOF (".", 8);Pode ser escrito na forma seguinte usando a reflexão:
Fas jogável; tente {método indexm = string.class. getMethod ("index0f", string.class, int.class); retornar (inteiro) index.invoke (str, ",", 8); } catch (noschmethodException e) {falha = e; } catch (InvocationTargeTexception e) {fas = e .getcause (); } catch (ilegalAccessException e) {falha = e; } jogue fas;Embora as verificações de segurança do compilador para chamadas diretas só possam ser executadas ao usar o Invoke em tempo de execução ao usar a reflexão, o código baseado em reflexão possui verificações de segurança semanticamente equivalentes ao código chamado direto. As verificações de acesso podem ser realizadas de uma maneira um pouco diferente - o gerente de segurança pode negar o acesso a um método em nosso pacote, mesmo que possamos chamá -lo diretamente.
Quando podemos usar essa forma de chamada, temos boas razões para evitá -la. Mas faria sentido se usarmos o método Invoke ou Get/Set ao gravar um depurador ou outro aplicativo genérico que precisa interpretar a entrada do usuário como operação em objetos. O objeto de método pode ser usado até certo ponto como um ponteiro de método semelhante ao de outros idiomas, mas temos melhores ferramentas, especialmente interfaces, classes abstratas e classes aninhadas, que podem ser usadas para lidar com problemas que geralmente são resolvidos com ponteiros de método em outros idiomas.