简体   繁体   中英

Java Passing in Type as Function Parameter

I come from a Python background and in Python you can pass in the type of an object as a parameter. But in Java you cannot do this, any tips on how to get something like this working?

private void function(Type TypeGoesHere)
    Stock s = new TypeGoesHere();
    s.analyze();
}

In Java you can pass a Class. You can do it like this:

private void function(Class c)

This is not very common procatice though. You can probably get wha you need by looking into Strategy pattern, or proper use of Object Oriented Programming (polymorphism).

If you are looking for a way to build some objects, look into Factory pattern.

If you want to create a generic class- look into this detailed answer: https://stackoverflow.com/a/1090488/1611957

Java does not support Python's way of referencing functions and classes. To achieve this behaviour, you have to use two advanced techniques: generics and reflection. Explaining these concepts is beyond the scope of a SO answer. You should read a Java guide to learn about them.

Yet here is an example how this would look like, assuming that the given class has a no-argument constructor:

public <T extends Stock> void analyzeNewStock(Class<T> clazz) throws Exception {
  Stock s = clazz.newInstance();
  s.analyze();
}

Then call this function with analyzeNewStock(MyStock.class) .

As this is a rather complicated and error-prone approach, you'd rather define an interface that creates Stock instances:

public interface StockProvider {
  Stock createStock(String value);
}

public class MyStockProvider implements StockProvider {
  private final String valueTwo;

  public MyStockProvider(String valueTwo) {
    this.valueTwo = valueTwo;
  }

  @Override
  public Stock createStock(String valueOne) {
    return new MyStock(valueOne, valueTwo);
  }
}

public class MyOtherClass {
  public void analyzeNewStock(StockProvider provider) {
    provider.createStock("Hi!").analyze();
  }

  public static void main(String[] args) {
    analyzeNewStock(new MyStockProvider("Hey!"));
  }
}

You could use generics . For example:

private <T> void function(Class<T> clazz) {
    try{
        T t = clazz.newInstance();
        //more code here
    }catch(InstantiationException | IllegalAccessException ex){
        ex.printStackTrace();
    }
}

The Class<T> clazz shows what type to instantiate. The try/catch is just to prevent errors from stopping your code. The same idea is expanded in this SO post . More info here .

However, I'm not really sure why you would want to do this. There should easily be a workaround using a simple interface. Since you already know that you want an object with type Stock , you could pass an implementation of the interface. For example:

//interface to implement
public interface Stock {
    public void analyze();
}

//rewrite of function
private void function(Stock s){
    s.analyze();
}

And using two ways to call function :

//first way
public class XYZ implements Stock{
    public void analyze(){
        //some code here
    }
}

//calling the function
function(new XYZ());

//second way
function(new Stock(){
    public void analyze(){
        //your code here
    }
});

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