Sefi Erlich
Sefi Erlich

Reputation: 161

create instance from client selection -java

I've been looking around the web for a while. I'm trying to create an instance of a subclass dynamically, let me explain:

I have the following class:

Public abstract  class Property

And a lot of sub class created from this class, for example the following two:

public   class PropertyDns extends Property

Public class PropretyNetBios extends Property

I want the client to choose one of the subclass name, and then I need to create an instance of that class.

I'm going to have a lot of subclass that extends Property so switch-case statements will be exhausting: So:

switch (user_input){
case "PropertyDns ": return new PropertyDns();
case "PropretyNetBios": return new PropretyNetBios();
.
.
.
}

will be terrible... any ideas?

Upvotes: 0

Views: 172

Answers (3)

Rafael Guillen
Rafael Guillen

Reputation: 1673

As I commented before, this problem can be solved with the Factory Pattern, if the number of classes is too large you can mix the Factory Pattern with an Annotation Processor to generate the factory. You need to create an annotation and a corresponding annotation processor.

Here is an example of the annotation you should create:

@Target(ElementType.TYPE) @Retention(RetentionPolicy.CLASS)    
public @interface Property {
    String name();
    Class type();
}

Your property classes will look like this:

@Property(name="DnsProperty", class=Property.class)
public class DnsProperty extends Property{
    ...
}

You need to implement your own processor extending the class

javax.annotation.processing.AbstractProcessor

and register it at

/META-INF/services/javax.annotation.processing.Processor

The idea is to annotate each class to provide it's name, and generate the factory statements with the annotation processor, saving you from writing the exhausting switch-case statements. Explaining the annotation processors, as switch-case statements can be exhausting, so, you can read about it in the Java documentation, here is a blog post explaining annotation processors and here is the source code.

Upvotes: 1

Akash Yadav
Akash Yadav

Reputation: 2421

You can use one of the following two ways to achieve the result:

  1. Create a factory method, which takes a String parameter, and based on the parameter, write up a switch to serve the required object.
  2. The second option (and the recommended approach here) would be to dynamically create an instance from the class name using Class.newInstance

Using the second approach would make your solution easily extendable, and the addition of new classes won't need any structural changes.

A sample implementation of the second approach would be like:

public Property getProperty(String name) {
    //Make sure the name contains full cannonical name of the class
    return (Property) Class.forName(name).newInstance();
}

Upvotes: 3

Rafael Guillen
Rafael Guillen

Reputation: 1673

You need a Factory and a proper naming system for you classes(for example an enumeration), read about Factory pattern. This should work for you.

public class PropertyFactory {
  public enum PropertyName {
    DNS,
    NET_BIOS
  }

  public Property createProperty(PropertyName name) {
    switch (name) {
        case DNS:
          return new PropertyDns();
        case NET_BIOS:
          return new PropretyNetBios(); 
    }
    return null; //Or throw an exception
  }
}

Upvotes: 0

Related Questions