1

I am trying to define a Java class which could be used for generic types, but I want to define the constructors for possible parameter types like Character, or an object type I can manually define.

The class I am trying to create is called:

public class Repeated<T> implements Pict {

private T[][] elements;

private double scale;

public Repeated(T[][] elems) {
    elements = elems;
}
}

So I want to add a constructor that adds a Character Array and does something specific if only T is the Type Character. Is it possible? Or should I make this an Interface, then implement it later?

2
  • 2
    It's not possible with constructors, but it may well be possible if you use static factory methods instead! Commented Nov 11, 2012 at 22:51
  • Due to type erasure, this isn't possible. Also, remember the KISS principle - if you really need generics, I'd look at what @Paul Bellora has described, otherwise leave it out. Commented Nov 12, 2012 at 10:47

2 Answers 2

2

So I want to add a constructor that adds a Character Array and does something specific if only T is the Type Character

Sounds like a good case for polymorphism:

public class RepeatedChars extends Repeated<Character> {

    public RepeatedChars(Character[][] chars) {
        super(chars);
        //do special stuff
    }

    //other character-specific logic if applicable
}

You could even hide this class as an implementation detail:

public class Repeated<T> implements Pict {

    ...

    private static class RepeatedChars extends Repeated<Character> {
        //see above
    }

    public static Repeated<Character> makeForChars(Character[][] chars) {
        return new RepeatedChars(chars);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

If you're going to do this with factory methods, you don't need subclasses. Just define a (most likely private) constructor Repeated(T[][] elems, boolean isCharsFlag). The factory methods can then pass the appropriate flag value to the constructor.
2

You should be able to do this:

public Repeated(T[][] elems) {
    elements = elems;
    boolean isCharacterArrayArray = false;
    if (elems != null) {
        for (T[] elt : elems) {
            if (elt != null && elt.length > 0) {
                isCharacterArrayArray = elt[0] instanceof Character;
                break;
            }
        }
    }
    if (isCharacterArrayArray) {
        // received a Character[][]
    }
}

However, because of type erasure, I don't think you can distinguish these calls:

new Repeated((Character[][]) null);
new Repeated((Integer[][]) null);

without passing some sort of explicit class argument.

EDIT With a class argument, it all becomes much simpler:

public Repeated(T[][] elems, Class<T> cls) {
    elements = elems;
    if (cls.equals(Character.class)) {
        // passed a Character[][]
    }
}

2 Comments

I'm not crazy about your solution, but you could just use Class.getComponentType() - that would account for empty arrays.
@PaulBellora - Excellent idea. It still wouldn't work for null arrays, though, since there's no object there to call getClass() on. I don't like my solution, either; passing a Class object fixes everything, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.