为了账号安全,请及时绑定邮箱和手机立即绑定

如何正确使用class类型的参数?

如何正确使用class类型的参数?

LEATH 2023-08-09 15:59:16
在java中,我想做这样的事情    public class Tata{         public static void f(){            //something        }        public static void g(){            //something        }    }    public class Titi{         public static void f(){            //something        }        public static void g(){            //something        }    }    public class Toto{        private Class c = Tata.class; //or Titi.class         public static void main(String[] args) {            c.f();            c.g();        }    }准确地说,我希望能够在类Tata和Titi之间自由切换,以使用它们各自的方法f或g。这没有按预期工作,因为我收到无法解析方法“f()”错误。只需替换cf(); 和cg(); 与Tata.f(); 和Tata.g(); 工作正常,但违背了使用参数的目的。怎么解决这个问题呢?
查看完整描述

3 回答

?
qq_花开花谢_0

TA贡献1835条经验 获得超6个赞

毕竟会把评论变成答案。处理你想要的事情的正确(Java)方法是使用接口。因此,在您的演示代码中,实现如下:


public interface TheFGFunctions {

    void f();

    void g();

}

public class Tata implements TheFGFunctions {

    @Override

    public void f() {

        //something

    }

    @Override

    public void g() {

        //something

    }

}

public class Titi implements TheFGFunctions {

    @Override

    public void f() {

        //something

    }

    @Override

    public void g() {

        //something

    }

}

public class Toto {

    private TheFGFunctions c;

    public Toto(TheFGFunctions c) {

        this.c = c;

    }

    public void notStaticFunction() {

        c.f();

        c.g();

    }

}

这种方式是完全类型安全的,可以处理零异常!


查看完整回答
反对 回复 2023-08-09
?
墨色风雨

TA贡献1853条经验 获得超6个赞

无法以多态方式访问静态方法。Java语言不支持它。

您当前的方法失败的原因是它c是类的实例Class,并且该类Class没有定义方法f()g()

(它定义的方法列在 的javadocClass中。请注意,这样Classfinal就无法使用额外的方法创建自定义子类。)


简单的替代方法是使用反射;例如

Class c = 

     Method f = c.getMethod("f");

     f.invoke(null);   // because it is static

但请注意:

  • 这不是静态类型安全的。编译器无法判断您何时错误地尝试f()在没有此类方法的类上使用静态。

  • 您需要处理一些例外情况;例如,缺少方法、不正确的签名、非静态方法、没有正确访问权限的方法。


其他答案建议创建一个接口和包装类以使某些静态方法可分派。它会工作,并且是编译时类型安全的(!),但需要编写大量样板代码。


@Michael Michailidis 评论道:

因此接口!

是的...有点。您只能对接口上声明的实例方法进行多态分派。Tata这意味着您必须拥有or的实例Titi,并调用它的方法。我对这个问题的解读是作者想避免这种情况。

(IMO,避免才是真正的问题。你最好不要试图避免实例方法。)

FWIW,您可以在接口中声明静态方法(自 Java 8 起),但它们的行为与在类中声明它们相同。你将无法发送...


查看完整回答
反对 回复 2023-08-09
?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

编写一个包装接口


interface CWrapper {

    void f();

    void g();

}

以及包含方法的每个类的包装类工厂方法


class CWrappers {

    CWrapper forTiti(Class<Titi> titiClass) {

        return new CWrapper() {

            void f() { Titi.f(); }

            void g() { Titi.g(); }

        }

    }

    // another factory method for Tata

}

然后你可以使用它:


public class Toto {

    private CWrapper c = CWrappers.forTata(Tata.class); //or forTiti(Titi.class)


    public static void main(String[] args) {

        c.f();

        c.g();

    }

}


查看完整回答
反对 回复 2023-08-09
  • 3 回答
  • 0 关注
  • 108 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信