简体   繁体   中英

Java - Instance method for specific generic instances

can I make a method that works on specific type of a generic class.

For example, I have my class below:

package utils;

public class MyArray<T> {
    // Constants
    private static final int INITIAL_SIZE = 10;

    // Instance Fields
    private T[] elms;
    private int size;

    // Constructor
    public MyArray () {
        elms = (T[]) new Object[INITIAL_SIZE];
        size = 0;
    }

    // Methods
    public void add (T elm) {
        if (elms.length == size)
            increaseSize();

        elms[size++] = elm;
    }

    @Override
    public String toString () {
        String str = "[" + elms[0];

        for (int i = 1; i < size; i++)
            str += ", " + elms[i];

        str += "]";

        return str;
    }

    // Helper Methods
    private void increaseSize () {
        T[] temp = (T[]) new Object[elms.length];
        for (int i = 0; i < temp.length; i++)
            temp[i] = elms[i];

        elms = (T[]) new Object[2 * temp.length];

        for (int i = 0; i < temp.length; i++)
            elms[i] = temp[i];
    }
}

Can I make a method that will work on MyArray<Integer> or MyArray<Long> and throws an exception on other types?

I tried doing the following:

public T sumOfElms () {
    if (T instanceof Integer) {
        // code here
    }
}

But it doesn't seem to work.

Any ideas or thoughts on how I can do it?

Like @Vishal K solution

You can change your constructor in this way:

  public MyArray (Class<T> clazz) { elms = (T[])java.lang.reflect.Array.newInstance(clazz,INITIAL_SIZE); size = 0; } 

And while creating the object of MyArray use the following code:

  MyArray<Integer> myArray = new MyArray<Integer>(Integer.class); 

You want to make this non generic method in a generic class so u have to take other strategy, instanceof is ugly.

public T sumOfElms () {
    if (T instanceof Integer) {
        // code here
    }
}

u have to extend this class to have functionality (inheritance or composition) like this

public class MyLongArray extends MyArray<Long> {

   public Long sumOfElms () {
      //code here
   }

}

or by Composition

public class MyLongArrayComposed {

   private MyArray<Long> myArray;

   public Long sumOfElms () {
      //code here
   }
}

You can change your constructor in this way:

public MyArray (Class<T> clazz) {
    elms = (T[])java.lang.reflect.Array.newInstance(clazz,INITIAL_SIZE);
    size = 0;
}

And while creating the object of MyArray use the following code:

MyArray<Integer> myArray = new MyArray<Integer>(Integer.class);

UPDATE Further if you want to make your method to work depending upon the type of elms then you can work as follows:

public void doSomething()
{
 if (elms instanceof Integer[])
 {
   ....
 }
}
public class MyArray<T> {

   ...

   private T[] elms;
   private int size;

   ...
   public boolean forEach( ArrayItemFct<T> fct ) {
      for( T t item ) {
         if( ! fct( item )) {
            return false;
         }
      }
      return true;
   }
}

class Summation extends ArrayItemFct<Integer> {

   public long sum = 0L;

   @Override boolean fct( Integer item ) {
      this.sum += item;
   }
}

usage 1:

MyArray< Integer > array = new MyArray<>();
... // add items
Summation summation = new Summation();
array.forEach( summation );
long sum = summation.sum;

usage 2:

MyArray< String > array = new MyArray<>();
... // add items
Concatenation concatenation = new Concatenation();
array.forEach( concatenation );
String concat = concatenation.concat;

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