如何使函数接受任何类型(不一定是对象)?

时间:2013-09-07 00:14:11

标签: java

我有一个功能

boolean isValid(/* what goes in here? */) {  
     //do stuff  
}

在函数签名中,我必须在参数列表中输入什么才能使方法接受可能属于任何类型(基元或对象)的单个参数?

我在这个网站和谷歌上搜索过,但我只能找到返回类型未知的情况。

4 个答案:

答案 0 :(得分:3)

如果您具有接受通用对象类型的函数,Java将创建任何基本数据类型的对象版本(即int的Integer)。

答案 1 :(得分:1)

阅读问题和评论,您似乎对编译语言的工作方式感觉有点偏差。

如果使函数只接受一种类型(例如String),那么如果调用者没有传递作为该类型实例的对象,则它将无法编译。 “不编译”意味着他们甚至无法在不修复错误的情况下运行程序。编译器会为您强制执行此类型的安全性,因此您不必担心这一点。

答案 2 :(得分:1)

我觉得你有点困惑。 我会尝试澄清一些事情:

  • 您可能知道方法的返回类型是将传递给调用该方法的代码部分的值(也称为客户端)。 Java中的每个方法/函数只能返回一种类型(我假设您熟悉基本多态,并且您知道IS A关系是什么......)。这是第一个澄清,你只能返回一种类型,但只能返回一个或多个对象(有数据结构类型)。

  • 参数是方法/函数的调用者/客户端可以传递给它进行处理的值。参数可以包含零个或多个参数,这意味着您可以根据需要传递任意数量的对象。

  • 参数与参数完全相同,它只是一个术语上的区别。我想对这些术语做准确,你可以说当你定义方法时参数是括号,而参数是调用方法时的那些括号。

  • 在返回类型或参数/参数中,您可以传递的两种类型是对象或基元类型。 如果使用Object类型的东西,这将允许您返回任何对象(Object是所有类的超类)。但原始类型不是对象,因此签名中的类型对象不允许传递数字,但有一个小技巧...... 在Java中有一些特殊类型的对象称为原始包装器(Integer,Double ...),这些对象是基元的对象表示,有时使用它们是因为它们具有一些内置函数,可以帮助程序员轻松操作数据(不是重点是,继续阅读...),每个表示数字基元类型的包装器,扩展一个名为Number的类,并且由于Java称为自动装箱的一个特性,您可以自动将基元传递给Wrappers。

无论如何,我不知道这是否是你想要的伎俩,但无论如何我只想建议你,没有理由做你正在尝试的事情,这听起来很奇怪,我不认为现实生活中的编程真的需要这样的东西。

看一下这段代码:

public static void main( String[] args )
{
    App app = new App();
    app.method(5);
}

public void method(Number number) {
    System.out.print(number);
}

另一种选择: 为了使参数具有通用性,我可以考虑的另一个例子是使用泛型。所以只是为了结束这个答案来证明我的观点,这里有一个方法可以让你传递任何你想要的东西,不管是原始的还是对象:

public class App 
{
    public static void main( String[] args )
    {
        App app = new App();
        app.method(5);

        app.someMethod(9);
        app.someMethod("Whatever");
        app.someMethod(true);
    }

    public void method(Number number) {
       System.out.println(number);
    }

    public <T> void someMethod(T t) {
       System.out.println(t);
    }

}

我希望你觉得这很有用,但我坚持认为你在现实生活中永远不会做这样的事情。

答案 3 :(得分:1)

阅读完评论之后,您似乎有业务需要对人们传递给您的任何对象进行有效处理,并且可能随着时间的推移您将不得不支持更多类型。

最简单的解决方案就像jtoomey所说的那样,制作像public boolean isValid(Object val)这样的方法。但是,请考虑您必须编写多少if语句,以及在需要新类型验证时修改代码的难度。

对我来说,我可能会做一些比提供单一方法更复杂的事情。我会利用工厂在类类型上创建验证器,如:

public interface Validator<T> {

   public boolean isValid(T val) {
   }
}

public class ValidatorFactory {

    public static ValidatorFactory create(String configFile) {
         /*read config and create new instance */
    }

    public Validator<T> createValidator(Class<T> clazz) {
         /* base on config and create validator base on type*/
    }
} 


public class Application {

    public static ValidatorFactory vFactory = ValidatorFactory.create() 

    public static void main(String[] args) {

         Object val = Arguments.getVal(); //assume this exists

         Validator<Object> validator = vFactory.create(val.class);
         if (validator == null) {
            System.out.println("not valid");
            return;
         }

         System.out.println(validator.isValid());
    }
}

请注意,我个人认为这是一个糟糕的解决方案,因为您丢弃了Java的类型安全功能。但如果你真的必须,拥有一个可配置的工厂将比一个接受任何类型的方法更好。使用Validator接口可以在编写验证代码时知道类型。