Load data from file in java - 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.

Related

Java create method in Interface and change the parameter type

How do I create an interface that when Overridden can have different types? Sometimes I would like the method to accept an item of type 'HtmlPage' and other times I would like it to take the type 'Document'. Later these could change to even more types.
Example:
public interface MyInterface{
void checkThis() throws Exception;
Output Show(Input input, String url) throws Exception;
}
public class HeadLevel extends MyInterface<HtmlPage,String>{
Output scrape(HtmlPage page, String url) throws Exception;
}
public class MyClass implements HeadLevel<Output>{
#Override
public void checkThis(Document page, String url){
}
}
I am thinking something like this should be achievable. I have tried looking around using keywords 'Overload' and 'Override' in my searches but cannot find something that can work like this. As you can see 'MyClass' has Overridden the method and has defined the parameters being used.
It feels that you are trying to force the code to solve a problem that you don't understand clearly. I like to step back and think about the connections between components and improve my design in such situations.
Maybe think along the lines that an HtmlPage is a Document. So, if you
extend an HtmlPage with a Document (public class HtmlPage extends Document). When an Interface method accepts Document, it will take HtmlPage. Assuming that you have control over the relationship between Document and HtmlPage, in other words, you are not using a third-party library. Once that is done, a method won't need to operate on two unrelated concepts.
I' am not clear about the definition of your problem, better naming might have helped, either way, a potential solution might look like this:
interface MyInterface{
<K extends Document> void checkThis(K htmlPage) throws Exception;
Output Show(Input input, String url) throws Exception;
}
class HeadLevel implements MyInterface{
public <K extends Document> void checkThis(K htmlPage) throws Exception
{
// Do something
}
public Output Show(Input input, String url) throws Exception{
return new Output();
}
public <K extends Document> Output scrape(K htmlPage, String url) throws Exception
{
return new Output();
}
}
class MyClass extends HeadLevel{
public MyClass() throws Exception
{
checkThis(new HtmlPage());
checkThis(new Document());
}
public <K extends Document> void checkThis(K htmlPage) throws Exception
{
super.checkThis(htmlPage);
}
}
class Document{
}
class HtmlPage extends Document
{
}
https://docs.oracle.com/javase/tutorial/java/generics/types.html
In this case you don't need any interface, it's not possible to do what you want, you need to understand the concept of interfaces before use it.
https://docs.oracle.com/javase/tutorial/java/concepts/interface.html
The implementation I was looking for turned out to not exist however there is a better way to be able to do what I was looking for using Input and Output.
public interface MyInterface<Input, Output> {
void checkThis(Input input, Output output) throws Exception;
Output Show(Input input, String url) throws Exception;
}
public class HeadLevel extends MyInterface<HtmlPage,String>{
Output scrape(HtmlPage page, String url) throws Exception;
}
public class MyClass implements HeadLevel<Output>{
#Override
public void checkThis(Document page, String url){
}
}
It seems the answer was actually under my nose. I misunderstood what Input/Output types are and how you can use them. Input and Output can be of any time that you expect to come in or go out of an application sort of speak.
Input is any information that is needed by your program to complete
its execution.There are many forms that program input may take
Input can take the form of many different types such as HtmlPage, Document, and String. Using input you can Override your method and have your desired types.
You can read more about Input and Output here

Java: Using a class as an parameter to describe a setups

I couldn't think of a good way to name this. Basically I'm have a program where I want to have a default "pattern" almost I guess of how something should function. But I wanted to allow the use to create their own implementation (This is like an API) of the class and use that as a parameter instead, with the functionality inside. Is this the most efficient way to do it? If you don't understand that bad description here is an example.
public class SimpleStyle extends AbstractStyle {
public void personalizedImplementation() {
// manipulate the program this way
}
}
Then in the method
public static void do(Class<? extends AbstractSyle> style) {
// Use reflection in herre to get the implementation and do it
}
Is there a better and more efficient way to do something like this
You should not use reflection for this task if you can avoid it. It is less readable and more error-prone than well designed interfaces.
The basic solution (I’m not sure whether you already considered it) is to simply pass instances of AbstractStyle to your method:
public static void doSomething(AbstractStyle style) {
style.personalizedImplementation();
}
public static void main(String[] args) {
do(new SimpleStyle());
}
If you cannot use this approach – this depends on the specific use case – you could define an additional interface that handles the creation of the AbstractStyle instance:
public interface StyleFactory {
AbstractStyle createStyle();
}
public class SimpleStyleFactory implements StyleFactory {
#Override
public SimpleStyle createStyle() {
return new SimpleStyle(/* ... */);
}
}
public static void doSomething(StyleFactory styleFactory) {
AbstractStyle style = styleFactory.createStyle();
style.personalizedImplementation();
}
public static void main(String[] args) {
do(new SimpleStyleFactory());
}
Note: do is a Java keyword, so it can’t be used as an identifier. I used doSomething instead.

Shadowing variable used in a default method of an interface in Java 8

Today I was thinking about a nice way to write less code for a common functionality that is required for different objects.
Inheritance can do the job but then the classes won't be able to inherit from anyone else, so I chose Interfaces.
So I have my interface with the functionality I will need for some objects:
public interface Test {
String message = "Hello from Interface!";
default void printMessage() {
System.out.println(message);
}
}
And then I can use it in any object without having to override/write any code more than just simply calling the method when needed:
public class TestingTest implements Test {
public String message = "Hello from Class!";
public TestingTest() {
printMessage();
}
public static void main(String[] args) {
new TestingTest();
}
}
It works like a charm! But... Then I thought, what if I want some of those objects to specify a different message without being required (optional), well first thing I thought was to shadow the interface variable, but it doesn't work, the default method keeps using the variable from the interface instead of the class variable (which shadowed it).
A solution of course would be to overload the printMessage method in the interface so it recieves the message as a parameter for when the user requires to specify the message, but is there any more elegant way? Something like simply just declaring a new message in the class?
The String message in the interface is static (AFAIK). So that scheme does not work.
You might do something (ugly) as:
default void printMessage(String... messages) {
if (messages.length == 0) {
messages = new String[] { "arrgg" };
}
System.out.println(messages[0]);
}
Fields have no inheritance, so the value can only stem from an overridable method like
public String message() { return "..."; }
What you want is a functionality in n classes that should also be modifiable, if needed.
To be honest, your example is a little bit abstract and thus my answer will be abstract, too.
public interface Test {
void printMessage();
default void printMessage(String message) {
System.out.println(message);
}
}
public class TestingTest {
private final test;
public TestingTest(Test test) {
this.test = test;
}
public void someMethod() {
test.printMessage("Hello from class");
}
}
Additionally, you would have a class that implements the interface and offers the message. This way you could group your objects, change the message, make more complex logging and you would actually see the dependency from outside.
In my opinion, you are misusing the interface. An interface offers public methods to call it from outside, but you want to use them inside like they were private functionalities for the class.
Just use objects instead.

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();
}
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!"));
}
}
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
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
}
});

How to create a method in a Java class that is accesible from only one other class

I was wondering if anyone had a pattern that would help me achieve the following:
We have a JPA entity called Employee and on it there is a setLineManager method. We also have a separate updateLineStructureService, which is a Spring-managed service bean. We want to try and ensure that this setLineManager method can only be called from updateLineStructureService and not directly from any other class.
Is there a way to allow the service access to this method without exposing it to any other classes? I am aware that I could give the method package level access and put the service in the same package as Employee, but that will not fit our package structure so I would prefer not to do that. I am also aware that I could make the method private and just access it through reflection in this one place, but I do not like that solution at all.
Any ideas?
You can inspect the stacktrace (using Throwable#getStackTrace()) and see if it contains the allowed method on specified position.
In the following code snippet, System.PrivateEmployee is not visible outside the System class. Thus effectively privateMethod is private and can only be called from within the System class. Since System.PrivateEmployee extends System.PublicEmployee it can be used outside the System class as System.PublicEmployee
public class System
{
public static interface PublicEmployee { void publicMethod ( ) ; }
private static interface PrivateEmployee extends PublicEmployee { void privateMethod ( ) ; }
}
Use an inner class only available to the other service class:
public class Employee
{
static {
LineStructureService.registerEmployeeHelper(new EmployeeHelper() {
#Override
public void setLineManager(Employee emp, Object foo) {
emp.setLineManager(foo);
}
});
}
public static void init() {}
private void setLineManager(Object foo) { }
}
public class LineStructureService
{
private static volatile EmployeeHelper _helper;
static {
// ensure that Employee class is loaded and helper registered
Employee.init();
}
public static synchronized void registerEmployeeHelper(EmployeeHelper helper) {
_helper = helper;
}
public void doSomething(Employee emp)
{
// now this class can call setLineManager on Employee
_helper.setLineManager(emp, blah);
}
public interface EmployeeHelper {
public void setLineManager(Employee emp, Object foo);
}
}
The only way that a class can access private methods of other classes is with inner classes. If that is not an option, this can't be done.
One approach is to make two forms of Employee.
"BasicEmployee" has all the methods except setLineManager(). "ExtendedEmployee" extends BasicEmployee and adds a public void setLineManager(). (I'm assuming these are classes, but they could also be interfaces instead) Underneath the hood, everything is really a FullEmployee (for clarity, you could make BasicEmployee abstract). But, in the code, in all the classes except UpdateLineStructureService, you declare it as a BasicEmployee. Only in UpdateLineStructureService is it declared as a FullEmployee. So, only UpdateLineStructureService has easy access to setLineManager()
Now, a rogue coder could always cast their BasicEmployee to an ExtendedEmployee to access setLineManager(), so this isn't totally secure. But it's a reasonable pattern to limit access.
You could use AOP (e.g. AspectJ or CDI) to intercept the call to setLineManager(); if the caller is updateLineStructureService() call the method; if not do nothing, or raise an exception or whatever.

Categories

Resources