Recuperando um Nome de Classe em Java
1. Visão geral
Neste tutorial, aprenderemos quatro maneiras de recuperar o nome de uma classe de métodos na APIClass:getSimpleName(), getName(), getTypeName()egetCanonicalName().
Esses métodos podem ser confusos devido aos nomes semelhantes e aos Javadocs um tanto vagos. Eles também têm algumas nuances quando se trata de tipos primitivos, tipos de objetos, classes internas ou anônimas e matrizes.
2. Recuperando Nome Simples
Vamos começar com o métodogetSimpleName().
Em Java, existem dois tipos de nomes:simpleequalified. A simple name consists of a unique identifier while a qualified name is a sequence of simple names separated by dots.
Como o próprio nome sugere,getSimpleName() retorna o nome simples da classe subjacente, que éthe name it has been given in the source code.
Vamos imaginar a seguinte classe:
package com.example.className;
public class RetrieveClassName {}
Seu nome simples seriaRetrieveClassName:
assertEquals("RetrieveClassName", RetrieveClassName.class.getSimpleName());
Também podemos obter tipos primitivos e matrizes de nomes simples. Para tipos primitivos que serão simplesmente seus nomes, comoint, boolean oufloat.
E para matrizes, o método retornaráthe simple name of the type of the array followed by a pair opening and closing brackets for each dimension of the array ([]):
RetrieveClassName[] names = new RetrieveClassName[];
assertEquals("RetrieveClassName[]", names.getClass().getSimpleName());
Consequentemente, para uma matriz bidimensionalString, chamargetSimpleName() em sua classe retornaráString[][].
Finalmente, há o caso específico de classes anônimas. Calling getSimpleName() on an anonymous class will return an empty string.
3. Recuperando outros nomes
Agora é hora de dar uma olhada em como obteríamos o nome de uma classe, nome do tipo ou nome canônico. Ao contrário degetSimpleName(), esses nomes visam fornecer mais informações sobre a classe.
O métodogetCanonicalName() sempre retorna o nome canônicoas defined in the Java Language Specification.
Quanto aos outros métodos, a saída pode diferir um pouco de acordo com os casos de uso. Veremos o que isso significa para diferentes tipos de objetos e primitivos.
3.1. Tipos primitivos
Vamos começar com tipos primitivos, pois eles são simples. For primitive types, all three methods getName(), getTypeName() and getCanonicalName() will return the same result as getSimpleName():
assertEquals("int", int.class.getName());
assertEquals("int", int.class.getTypeName());
assertEquals("int", int.class.getCanonicalName());
3.2. Tipos de Objetos
Agora veremos como esses métodos funcionam com tipos de objeto. Seu comportamento é geralmente o mesmo:they all return the canonical name of the class.
Na maioria dos casos, esse é um nome qualificado que contém todos os nomes simples dos pacotes de classes, bem como o nome simples da classe:
assertEquals("com.example.className.RetrieveClassName", RetrieveClassName.class.getName());
assertEquals("com.example.className.RetrieveClassName", RetrieveClassName.class.getTypeName());
assertEquals("com.example.className.RetrieveClassName", RetrieveClassName.class.getSimpleName());
3.3. Classes internas
O que vimos na seção anterior é o comportamento geral dessas chamadas de método, mas há algumas exceções.
Classes internas são uma delas. Os métodosgetName() andgetTypeName() se comportam de maneira diferente do métodogetCanonicalName() para classes internas.
getCanonicalName() still returns the canonical name of the class, que é o nome canônico da classe envolvente mais o nome simples da classe interna separado por um ponto.
Por outro lado, os métodosgetName() andgetTypeName() retornam praticamente o mesmo, masuse a dollar as the separator between the enclosing class canonical name and the inner class simple name.
Vamos imaginar uma classe internaInnerClass de nossoRetrieveClassName:
public class RetrieveClassName {
public class InnerClass {}
}
Então cada chamada indica a classe interna de uma maneira ligeiramente diferente:
assertEquals("com.example.RetrieveClassName.InnerClass",
RetrieveClassName.InnerClass.class.getCanonicalName());
assertEquals("com.example.RetrieveClassName$InnerClass",
RetrieveClassName.InnerClass.class.getName());
assertEquals("com.example.RetrieveClassName$InnerClass",
RetrieveClassName.InnerClass.class.getTypeName());
3.4. Classes anônimas
Classes anônimas são outra exceção.
Como já vimos, eles não têm um nome simples, masthey also don’t have a canonical name. Portanto,getCanonicalName() não retorna nada. In opposition to getSimpleName(), getCanonicalName() will return null e não uma string vazia quando chamada em uma classe anônima.
Já paragetName()egetTypeName() eles retornarãocalling class canonical name followed by a dollar and a number representing the position of the anonymous class among all anonymous classes created in the calling class.
Vamos ilustrar isso com um exemplo. Vamos criar aqui duas classes anônimas e chamargetName() na primeira egetTypeName() filho na segunda, declarando-as emcom.example.Main:
assertEquals("com.example.Main$1", new RetrieveClassName() {}.getClass().getName());
assertEquals("com.example.Main$2", new RetrieveClassName() {}.getClass().getTypeName());
Devemos observar que a segunda chamada retorna um nome com um número aumentado em seu final, pois é aplicado na segunda classe anônima.
3.5. Matrizes
Finalmente, vamos ver como os arrays são tratados pelos três métodos acima.
Para indicar que estamos lidando com matrizes, cada método atualizará seu resultado padrão. The getTypeName() and getCanonicalName() methods will append pairs of brackets to their result.
Vejamos o seguinte exemplo onde chamamosgetTypeName() andgetCanonicalName() em uma matriz bidimensionalInnerClass:
assertEquals("com.example.RetrieveClassName$InnerClass[][]",
RetrieveClassName.InnerClass[][].class.getTypeName());
assertEquals("com.example.RetrieveClassName.InnerClass[][]",
RetrieveClassName.InnerClass[][].class.getCanonicalName());
Observe como a primeira chamada usa um dólar em vez de um ponto para separar a parte da classe interna do restante do nome.
Vamos agora ver como funciona o métodogetName(). Quando chamado em uma matriz de tipo primitivo, ele retornaráan opening bracket and a letter representing the primitive type. Vejamos isso com o exemplo a seguir, chamando esse método em uma matriz de inteiros primitivos bidimensional:
assertEquals("[[I", int[][].class.getName());
Por outro lado, quando chamado em um array de objetos, eleadd an opening bracket and the L letter to its standard result and finish with a semi-colon. Vamos tentar em uma matriz deRetrieveClassName:
assertEquals("[Lcom.example.className.RetrieveClassName;", RetrieveClassName[].class.getName());
4. Conclusão
Neste artigo, analisamos quatro métodos para acessar um nome de classe em Java. Esses métodos são:getSimpleName(), getName(), getTypeName() egetCanonicalName().
Aprendemos que o primeiro retorna apenas o nome do código-fonte de uma classe, enquanto os outros fornecem mais informações, como nome do pacote e uma indicação sobre se a classe é interna ou anônima.
O código deste artigo pode ser encontradoover on GitHub.