Pergunta

Digamos que eu tenho uma classe base chamada Entity. Nessa classe, tenho um método estático para recuperar o nome da classe:

class Entity {
    public static String getClass() {
        return Entity.class.getClass();
    }
}

Agora tenho outra aula estendê -lo.

class User extends Entity {
}

Eu quero obter o nome da classe do usuário:

System.out.println(User.getClass());

Meu objetivo é ver a saída "com.packagename.user" no console, mas, em vez disso, vou acabar com "com.packagename.entity", já que a classe de entidade está sendo referenciada diretamente do método estático.

Se esse não fosse um método estático, isso poderia ser facilmente resolvido usando o this palavra -chave dentro do Entity classe (ou seja: return this.class.getClass()). No entanto, preciso que esse método permaneça estático. Alguma sugestão sobre como abordar isso?

Foi útil?

Solução

Não é possivel. Os métodos estáticos não são polimórficos de tempo de execução de forma alguma. É absolutamente impossível distinguir esses casos:

System.out.println(Entity.getClass());
System.out.println(User.getClass());

Eles compilam com o mesmo código de byte (assumindo que o método é definido em Entity).

Além disso, como você chamaria esse método de uma maneira que faria sentido para ser polimórfico?

Outras dicas

Não faça do método estático. A questão é que quando você invoca getClass() Você está chamando o método na super classe - os métodos estáticos não são herdados. Além Object.getClass(), o que é confuso.

Se você precisar registrar o nome da classe na superclasse, use

return this.getClass().getName();

Isso retornará "entidade" quando você tiver um Entity instância, "usuário" quando você tem um User instância, etc.

Sua pergunta é ambígua, mas até onde posso dizer que você quer saber a classe atual de um método estático. O fato de as classes herdarem um do outro é irrelevante, mas, pelo bem da discussão, também a implementei dessa maneira.

class Parent {
    public static void printClass() {
      System.out.println(Thread.currentThread().getStackTrace()[2].getClassName());
    }
}

public class Test extends Parent {
    public static void main(String[] args) {
      printClass();
    }
}

Isso funciona para mim

this.getClass().asSubclass(this.getClass())

Mas não tenho certeza de como funciona.

A superclasse nem deve saber da existência da subclasse, muito menos operações com base no nome totalmente qualificado da subclasse. Se você precisar de operações com base no que é a classe exata e não pode desempenhar a função necessária por herança, você deve fazer algo nesse sentido:

public class MyClassUtil
{
    public static String doWorkBasedOnClass(Class<?> clazz)
    {
        if(clazz == MyNormalClass.class)
        {
            // Stuff with MyNormalClass
            // Will not work for subclasses of MyNormalClass
        }

        if(isSubclassOf(clazz, MyNormalSuperclass.class))
        {
            // Stuff with MyNormalSuperclass or any subclasses
        }

        // Similar code for interface implementations
    }

    private static boolean isSubclassOf(Class<?> subclass, Class<?> superclass)
    {
        if(subclass == superclass || superclass == Object.class) return true;

        while(subclass != superclass && subclass != Object.class)
        {
            subclass = subclass.getSuperclass();
        }
        return false;
    }
}

(Código não testado)

Esta classe também não sabe sobre suas próprias subclasses, mas usa o Class classe para executar operações. Muito provavelmente, ainda estará fortemente ligado às implementações (geralmente uma coisa ruim, ou se não é ruim, não é especialmente Boa), mas acho que uma estrutura como essa é melhor do que uma superclasse, descobrindo quais são todas as suas subclasses.

Por que você deseja implementar seu próprio método getClass ()? Você pode simplesmente usar

System.out.println(User.class);

Editar (para elaborar um pouco): você deseja que o método seja estático. Nesse caso, você deve chamar o método na classe cujo nome de classe você deseja, seja a subclasse ou a super classe. Então, em vez de ligar MyClass.getClass(), você pode simplesmente ligar MyClass.class ou MyClass.class.getName().

Além disso, você está criando um static método com a mesma assinatura que o Object.getClass() Método da instância, que não compilará.

  1. Crie uma variável de sequência de membros na superclasse.
  2. Adicione o this.getClass (). GetName () a um construtor que armazena o valor na variável String de membro.
  3. Crie um getter para retornar o nome.

Cada vez que a classe estendida é instanciada, seu nome será armazenado na string e acessível com o getter.

Um método estático está associado a uma classe, não a um objeto específico.

Considere como isso funcionaria se houvesse várias subclasses - por exemplo, o administrador também é uma entidade. Como seu método de entidade estática, associado apenas à classe da entidade, saberia qual subclasse você queria?

Você poderia:

  • Use o método getClass () existente.
  • Passe um argumento para o seu método estático getClass () e chame um método de instância nesse objeto.
  • Torne seu método não estático e renomeie-o.

Se eu entender sua pergunta corretamente, acho que a única maneira de conseguir o que deseja é reimplementar o método estático em cada subclasse, por exemplo:

class Entity {
    public static String getMyClass() {
        return Entity.class.getName();
    }
}

class Derived extends Entity {
    public static String getMyClass() {
        return Derived.class.getName();
    }
}

Isso imprimirá o pacote. Bagunçado, mas ei, se essas são suas restrições ...

Se eu estou acertando, você deseja usar sua sub -classe na classe base no método estático, acho que você pode fazer isso passando um parâmetro de classe para o método

class Entity {
    public static void useClass(Class c) {
        System.out.println(c);
        // to do code here
    }
}

class User extends Entity {
}

class main{
    public static void main(String[] args){
        Entity.useClass(Entity.class);
    }
}

Meu contexto: entidade superclass com subclasses para objetos XML. Minha solução: crie uma variável de classe na superclasse

Class<?> claz;

Então, na subclasse, eu definiria a variável da superclasse no construtor

public class SubClass {
   public SubClass() {
     claz = this.getClass();
   }
}

É muito simples feito por

User.getClass (). GetSuperclass ()

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top