简体   繁体   中英

Create an object with a String and method overloading

I have a String which can either be of Double or Integer type or some other type. I first need to create a Double or Integer object and then send it over to a overloaded method. Here's my code so far;

public void doStuff1(object obj, String dataType){

 if ("Double".equalsIgnoreCase(dataType)) {
        doStuff2(Double.valueOf(obj.toString()));
    } else if ("Integer".equalsIgnoreCase(dataType)) {
        doStuff2(Integer.valueOf(obj.toString()));
    }

 }

 public void doStuff2(double d1){
   //do some double related stuff here
 }

 public void doStuff2(int d1){
   //do some int related stuff here
 }

I'd like to do this without if/else, with something like this;

Class<?> theClass = Class.forName(dataType);

The problem is 'theClass' still can't be cast to either double or int. I would be gratefull for any ideas. Thanks.

Found a related thread; Overloading in Java and multiple dispatch

This is not just a problem of dealing with primitive types.

Which method to call is decided in compile time , that is, if you want to be able to call different methods depending on the type of the arguments, you'll need several calls (ie you need the if-construct).

In other words, it wouldn't work even if doStuff2 took Integer and Double as arguments (your code is basically as good as it gets).

(In fancy words, this is due to the fact that Java has single dispatch . To emulate multiple dispatch you either need to use conditional statements or a visitor pattern.)

As aioobe says, the choice between overloaded methods is made at compile time based on the static types of the arguments.

If you want to simulate overload choice at runtime, you will need to do some complicated runtime analysis of the different possible methods. It would go something like this:

  1. get all declared methods of the class that declared doStuff2 .
  2. filter out the methods whose name is not doStuff2 .
  3. filter out the methods whose argument type cannot be assigned from the (dynamic) type of the argument value.
  4. of the remaining methods, pick the one that is the best match ... taking care to deal with "ties" as ambiguous.

This will be tricky to code, and trickier if you also throw in handling of primitive types. It will also make the method calls expensive.


Frankly, some kind of hard-wired dispatching is much simpler. If you don't like if / else tests (or switching on a String in Java 7), then you could do something like this.

Map<String, Operation> map = ...
map.put("Double", new Operation(){
    public void doIt(Object obj) {
        doStuff2((Double) obj);
    }});
map.put("Integer", new Operation(){
    public void doIt(Object obj) {
        doStuff2((Integer) obj);
    }});
...
map.get(typeName).doIt(obj);

... which at least allows you to "plug in" support for new types dynamically.

Since the method call is decided at compile time as the another answer told you, overloading won't work for you. I think that this problem can be solved with inheritance. So you write a base class with yourMethod() and override it in your derived classes.

If you resort to reflection, you'll only have to deal specially with primitive types. So your technique can work, but with the addition of a few explicit tests. If you need to reflectively find a method that accepts a primitive double , use double.class .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM