Java:从静态方法中获取继承类的类

Posted

技术标签:

【中文标题】Java:从静态方法中获取继承类的类【英文标题】:Java: get the class of the inherited class from a static method 【发布时间】:2012-02-01 00:22:06 【问题描述】:

我在 Java 中有以下问题: 我有一个基类和一个派生类,我在基类中有一个方法。当我通过 Derived 调用 Base 的 foo 方法时,我想获取 Derived 的类。 foo 方法可以是通用的,如果可以这样做的话。

class Base

    static void foo()
    
        // I want to get Derived class here
        // Derived.class
    


class Derived extends Base



Derived.foo();

感谢您的帮助!

大卫

【问题讨论】:

我不确定这是否可行,而不是像您那样使用静态方法。 “我想上 Derived 的课程”,这似乎是一件奇怪的事情。是什么原因?可能有更好的方法来解决您的实际问题 我有一个名为 ActiveModel 的模型,我想要一个类似 Rails 的接口,例如:Listbrands = Brand.all();并且 Brand 从 ActiveModel 扩展(ActiveModel 具有 all 功能),现在我必须将 Brand.class 传递给 all 函数才能为我的资源生成一个 url,例如:localhost/brands.json 我的目标是删除 Brand.class来自 List 品牌 = Brand.all(Brand.class) @seriakillaz 因为 Java 没有元类,所以你不能真正正确地伪造类似 Rails 的 API。使用单独的 DAO 类及其实例方法,而 Rails 会在类对象上使用实例方法。 @seriakillaz:Inerdial 是正确的。 Java 中的静态方法不够强大,无法为您提供所描述的行为。在 Java 中实现这种事情的正常方法是将您的 Brand 类转换为 instance 对象;然后客户端会调用类似brands().all() 的方法,其中brands() 是一个返回对象的方法,该对象的行为与您希望Brand 的行为相同。 【参考方案1】:

这不是静态方法的工作方式。您必须实现Derived.foo(),做任何对Derived 特殊的事情,然后该方法调用Base.foo()。如果你真的需要类型信息,你可以创建Base.foo0(Class klass)

但老实说,任何需要知道调用它的类的类型的静态方法都应该是实例方法。

【讨论】:

是的,实际上这就是我首先解决这个问题的方法【参考方案2】:

好吧,Derived.foo() 的调用者知道他们在调用什么,所以你可以改变你的方法:

class Base

    static void foo(Class< T > calledBy)
    
        // I want to get Derived class here
        // Derived.class
    


class Derived extends Base



Derived.foo(Derived.class);

【讨论】:

【参考方案3】:

static 方法不会被继承。具有相同签名的静态方法只能隐藏超类中的相似方法。这意味着你永远不会看到你可能想要的结果——你总是确切地知道封闭类。静态方法永远不可能以某种方式“在”另一个类中。所以根本不可能产生想要的结果。由于这个原因,从子类或实例调用静态方法是一个坏主意,因为它只是隐藏了真正的类。 (IDE 和静态代码分析工具可以标记或纠正这一点。)

来源:

JLShttp://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#227961 http://docs.oracle.com/javase/tutorial/java/IandI/override.html

因此,适用于继承方法的方法不适用于static 未继承的方法。

class Base 
    static void foo() 
        // Only the static context is available here so you can't get class dynamic class information
    
    void bar() 
        System.out.println(getClass());
    

class Derived extends Base 

class Another extends Base 
    static void foo() 
         // No super call possible!
         // This method hides the static method in the super class, it does not override it.
    
    void bar() 
         super.bar();
    


Derived derived = new Derived();
derived.bar(); // "class Derived"
Base base = new Base();
base.bar(); // "class Base"

// These are only "shortcuts" for Base.foo() that all work...
derived.foo(); // non-static context
Derived.foo(); // could be hidden by a method with same signature in Derived 
base.foo(); // non-static context

Base.foo(); // Correct way to call the method

Another a = new Another();
a.foo(); // non-static context
Another.foo(); 

语言允许这样做是个好主意吗? - 嗯。我认为这说明 IDE 和代码分析工具会发出警告,甚至可以自动纠正。

【讨论】:

【参考方案4】:

不可能,Derived.foo() 只会提供Base.foo() 的代码。

【讨论】:

【参考方案5】:
Derived.foo();

这个转到Derived中定义的foo,如果那里定义了一个:

class Base 
    static void foo() 
    System.out.println("Base");
    


class Der extends Base 
    static void foo() 
    System.out.println("Der");
    


class Check 
    public static void main(String[] args) 
    Base.foo();
    Der.foo();
    

当我运行它时:

javac -g Check.java && java Check 
Base 
Der

那么你的问题是什么?如果您要求每个派生类 implement foo 在 Java 中是不可能执行的。

【讨论】:

问题是:没有Derived.foo,但在foo 中仍将Derived 作为类名,就像在非静态方法中一样。 我?对不起,我想我没有得到你的问题。问题中的示例显示了 OP 想要什么,但这是不可能的。

以上是关于Java:从静态方法中获取继承类的类的主要内容,如果未能解决你的问题,请参考以下文章

Typescript中的类

android其他类怎么调用继承自activity的类(mainactivity)中的非静态方法?

关于JAVA

java中有哪些类型的方法,如何调用它们?

Java中静态变量与静态方法的继承

java中静态变量与静态方法的继承(转)