简体   繁体   中英

Load data from file in java

I have the following class:

public class DataService {

  static <T> void load(Structure structure, String path, DataServiceType dataService) {
     //do smth
  }

  private interface DataServiceType<T> {
      //do smth
  }

  private static class DataServiceInteger implements DataServiceType<Integer> {
      //do smth
  }

  private static class DataServiceString implements DataServiceType<String> {
      //do smth
  }

}

I want to add there two following methods:

public static void load(Structure<Integer> structure,String path) throws IOException {
    load(structure,path,new DataServiceInteger());
}
public static void load(Structure<String> structure,String path) throws IOException {
    load(structure,path,new DataServiceString());
}

but both methods have same erasure. How can I achive it without changing methods names?

EDIT

I wasn't accurate. Classes implement DataServiceType have mathod :

void getDataFromString(String in, T out);

(they are paresers) Reading from file is held in mehod static <T> void load(Structure structure, String path, DataServiceType dataService) from DataService, so M. le Rutte's solution wouldn't be good for me, because I would have to repeat myself. Is it possible to implement berry's soulution for my problem?

As you already found out, due to type erasure the runtime would not be able to distinguish between the different methods. Either the name must be different, or the arguments must be different.

However, you use a static method. My personal choice would to be to use specific instances of a DataService :

public interface DataService<T> {
     Structure<T> load(Path path);
}


public StringDataService implements DataService<String> {
    public Structure<String> load(Path path) {
        ...
    }
}

public IntDataService implements DataService<Integer> {
   public Structure<Integer> load(Path path) {
       ...
   }
}

You cannot. The way type erasure works in Java, is that a 'hidden' ( synthetic ) method is created by the compiler during compilation which casts the object from some superclass (usually Object ) to the correct type. As there are two different types in your example, the Java compiler does not know which to cast since both name and the rest of the parameters match completely.

It might be good practice to name the methods differently either way, as loading a String and loading an integer may not necessarily be handled exactly the same way. For example, you might need to load into memory a list of user input strings: in this case, the string might need to be sanitized first.

As said already, you can't do it exactly as described. However, you could do it by adding generic parameters to the load() method itself, and then making a generic DataServiceClazz type (as oppose to separate DataServiceInteger , DataServiceString classes) that implements your DataServiceType interface:

private static class DataServiceClazz<T> implements DataServiceType<T> { //Replaces DataServiceInteger, DataServiceString, etc.
    //do smth
}

public static <T> void load(Structure<T> structure, String path) throws IOException {
    load(structure, path, new DataServiceClazz<>());
}

This may not work, depending on your use case, since you won't be able to use different logic based on the type of T - but it's the closest pattern to what you have currently.

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