How to check class validity with generic class - java

I'm working on code where I have to cast base class onto derived one where I have an array of generic types that are derived by the base on.
For example, I have Base and Derived1, Derived2 and I put them into Class[]{Derived1.class, Derived2.class} and I pass this array to the constructor of the class.
In this constructor, I have to create instances of these derived classes and I don't know how to do that because I get the info that Class and Base are incompatible.
Here is my code example
public abstract class Base {
public abstract Base create(String s);
}
public class Derived extends Base {
java.lang.Integer value;
private static Derived integer = new Derived();
public static Derived getInstance(){
return integer;
}
public Base create(String s) {
value = java.lang.Integer.parseInt(s);
return this;
}
}
public class Clazz {
Class<? extends Base> type;
ArrayList<Base> arrayList;
public Class<? extends Base> getType() {
return type;
}
}
public class AnotherClazz{
ArrayList<Clazz> clazzArrayList;
Class<? extends Base>[] types;
AnotherClazz(Class<? extends Base>[] args){
clazzArrayList = new ArrayList<>();
types = args; // assuming I pass 2 elements in array
String[] strings = new String[]{"1","2"};
for (int i=0; i<args.length; ++i){
if (types[i] instanceof Base){
// here i want to check validity of class
}
}
for (int i=0; i<strings.length; ++i){
clazzArrayList.get(i).arrayList.add(((types[i]) Base).getInstance().create(strings[i]));
//here i want to create instance of object from type assigned to specific column
}
}
Thanks for the help.

To check the validity, try this
if (types[i].getClass().isAssignableFrom(Base.class))

If I read the question correctly, you want to create a few instances of derived classes that all have the same constructor arguments. If that is the case, then you need to give each derived class the same constructor (it does not need to be in the base class) and use Constructor.newInstance(parameters) to create the instances. Further, since you want to ensure that each derived class extents the base class then you will want to use Class.isAssignableFrom(class). For example,
import java.lang.reflect.Constructor;
public class SO52930530 {
public abstract static class Base {
public abstract <T> T getValue();
}
public static class Derived1 extends Base {
String value;
public Derived1(String value) {
this.value = value;
}
public <T> T getValue() {
return (T) value;
}
}
public static class Derived2 extends Base {
Integer value;
public Derived2(String value) {
this.value = new Integer(value);
}
public <T> T getValue() {
return (T) value;
}
}
public static void main(String... args) throws Exception {
Class<? extends Base>[] extensions = new Class[]{Derived1.class, Derived2.class};
String[] values = new String[]{"a", "1"};
Base[] instances = new Base[values.length];
for (int i = 0; i < instances.length; i++) {
Class extension = extensions[i];
if (Base.class.isAssignableFrom(extension)) {
Constructor constructor = extension.getConstructor(String.class);
instances[i] = (Base) constructor.newInstance(values[i]);
}
}
for (int i = 0; i < instances.length; i++) {
System.out.printf("%d %s %s\n", i, instances[i].getClass(), instances[i].getValue());
}
}
}
I hope this helps.

Thanks for helping with checking validity (it works!) but I still don't get this newInstance creation because I have to read data from .csv file and my derived classes are in fact "wrappers" for primitive types like int, float, etc. and I am supposed to create new object using methods getInstance() and create(string s), so it looks like this:
public static class Derived1 extends Base { //Integer wrapper
Integer value;
public Derived1(Integer value) {
this.value = value;
}
private static Integer integer = new Integer();
public static Integer getInstance(){
return integer;
}
private Integer(){};
public Base create(String s) {
value = java.lang.Integer.parseInt(s);
return this;
}
}
and I don't know how to use Class to cast to appriopriate type.

Related

Java: is there a way for function to allow all child class as return type using generics?

Coming across a problem that I could not make a function to allow a generic return type for all the child class of a parent class.
Is there a way to create a function that allows me to return any of these children class type base on an argument?
I have the following parent class:
abstract class Number {
int res = 1;
abstract static class Builder<T extends Builder<T>> {
int res = 100;
public T setNum(int num) {
this.res = num;
return self();
}
abstract Number build();
abstract T self();
}
Number(Builder<?> builder) {
res = builder.res;
}
}
and some children class:
class One extends Number{
private int size = 1;
static class Builder extends Number.Builder<Builder> {
private int size = -1;
public Builder setSize(int size) {
this.size = size;
return self();
}
#Override
public One build() {
return new One(this);
}
#Override
protected Builder self() {
return this;
}
}
private One(Builder builder) {
super(builder);
size = builder.size;
}
}
class Two extends Number {
private String size = String.valueOf(1);
static class Builder extends Number.Builder<Builder> {
private String size;
public Builder setSize(String size) {
this.size = size;
return self();
}
#Override
public Two build() {
return new Two(this);
}
#Override
protected Builder self() {
return this;
}
}
private Two(Builder builder) {
super(builder);
size = builder.size;
}
}
Note the parent class and child classes are not done yet, but it is going to have a similar format with just more fields so this would still apply
This is something that I want to achieve:
public <T> T loadNumber(String id) {
if (id.equals('1')) {
return new ONE.Builder.build(); // this will report error right now
}
elif (id.equals('2')) {
return new TWO.Builder.build(); // this will report error right now
}
return null;
}
The problem is that type arguments are specified by the caller. Your method
public <T> T loadNumber(String id) {
can be called like
Two two = loadNumber("One");
causing the compiler to infer
Two two = loadNumber<Two>("One");
which is why the compiler expects your method implementation to conjure a T out of thin air, and is not satisfied with a One. After all, T could stand for Two, as in the example above, and One isn't Two.
Put differently, the method signature
public <T> T loadNumber(String id) {
doesn't make sense, because the method must return a T, but has no way to determine, at runtime, what T is (due to type erasure, methods can't reflect on their type parameters).
So you have two choices:
Either you return the base type
public Number loadNumber(String id) {
and have the caller, who presumably knows which type the id he passed corresponds to, cast it to that type,
or you use an ID that whose type is itself generic and describes the type it maps to:
interface Builder<P extends Number, B extends Builder<P>> {
P build();
B self();
}
interface ID<P extends Number> {
Builder<P, ?> builder();
static ID<One> one = One.Builder::new;
static ID<Two> two = Two.Builder::new;
}
and then you can declare
public <N extends Number> N loadNumber(ID<N> id) {
return id.builder().build();
}
and use it like
One one = loadNumber(ID.one);
Two two = loadNumber(ID.two);
but not
One one = loadNumber(ID.two); // compilation error
You should be able to return any child class by simply using the parent class as a return type, in your case:
public Number loadNumber(String id) {
// your code implementation
}
Now, to save this into a variable you can use the same logic and declare the variable as the parent type. After the method returns, the variable will be casted into the whatever child class instance it returned, for example in your case:
Number obj = loadNumber("1");
The obj object will cast to an instance of One class. You can test this by printing out the object class after the above line:
System.out.println(obj.getClass());
This should print out class One or the name of whatever child class you saved into the variable.

Inheritance and Generics in Java

so I am making a project and I have some questions about inheritance.
I have two classes, named Attribute and NumericalAttribute. The first one:
public class Attribute {
Attribute() {}
Attribute(String type) {}
}
(which should be abstract, but i need to instantiate it so it can't be)
and the other one:
public class NumericalAttribute extends Attribute {
double value;
NumericalAttribute(String value) { this.value = Double.parseDouble(value); }
public double getAtr(Attribute atr) { return this.value; }
}
I have multiple children of Attribute, and each one of them has the same structure but it represents another type (string, int, boolean). The thing is I need some kind of method to return the "value" variable (which I do have in NumericalAttribute) but for the attribute class. But I can't create a method in Attribute, since each one of the sons will have a different type of return. So is there any way so that I can obtain the "value" variable through Attribute?
Thank you very much!
public static Atributo transformAtributo(String tipo, String valor) {
Atributo atr = new Atributo();
if (tipo.equals("bool")) atr = new AtributoBoolean(valor);
else if (tipo.equals("string")) atr = new AtributoCategorico(valor);
else if (tipo.equals("num")) atr = new AtributoNumerico(valor);
else if (tipo.equals("set")) atr = new AtributoCategoricoMultiple(valor);
else if (tipo.equals("fecha")) atr = null;
return atr;
}
This is what you are looking for:
public abstract class Attribute<T> {
public abstract T getValue(Attribute attr);
}
public class NumericalAttribute extends Attribute<Double> {
double value;
#Override
public Double getValue(Attribute attr) {
return value;
}
}
public class TextAttribute extends Attribute<String> {
String value;
#Override
public String getValue(Attribute attr) {
return value;
}
}
Attribute<T> is a generic class. The return type is declared on each concrete class.

Comparator for Optional<T>

I have abstract class OptionalComparator<T extends Comparable<T>> implements Comparator<Optional<T>>
So far, so good.
Following the model used by Optional itself, I figured it would be best to have a single instance of this class, and cast it when necessary (for example, to OptionalComparator<Integer>).
So I made private static final OptionalComparator<? extends Comparable<?>> ABSENT_FIRST.
The trouble came when I tried to assign a value. What should the type be?
new OptionalComparator<Comparable<Object>>() {...} doesn't work.
new OptionalComparator<Comparable<Comparable<Object>>>() {...} doesn't work.
new OptionalComparator<Integer>() {...} does work, for example, but I want the least-specific type possible.
What am I doing wrong? How can I make a base-case instance of this class?
You can have multiple implementations of OptionalComparator like this:
private static final OptionalComparator<? extends Comparable<?>> ABSENT_FIRST = new AbsentFirst<>();
private static final OptionalComparator<? extends Comparable<?>> ABSENT_LAST = new AbsentLast<>();
private interface OptionalComparator<T extends Comparable<T>> extends Comparator<Optional<T>> { }
private static class AbsentFirst<T extends Comparable<T>> implements OptionalComparator<T> {
#Override
public int compare(Optional<T> obj1, Optional<T> obj2) {
if (obj1.isPresent() && obj2.isPresent()) {
return obj1.get().compareTo(obj2.get());
} else if (obj1.isPresent()) {
return -1;
} else if (obj2.isPresent()) {
return 1;
} else {
return 0;
}
}
}
private static class AbsentLast<T extends Comparable<T>> implements OptionalComparator<T> {
#Override
public int compare(Optional<T> obj1, Optional<T> obj2) {
if (obj1.isPresent() && obj2.isPresent()) {
return obj1.get().compareTo(obj2.get());
} else if (obj1.isPresent()) {
return 1;
} else if (obj2.isPresent()) {
return -1;
} else {
return 0;
}
}
}
static <T extends Comparable<T>> OptionalComparator<T> absentFirstComparator() {
#SuppressWarnings("unchecked")
OptionalComparator<T> comp = (OptionalComparator<T>) ABSENT_FIRST;
return comp;
}
static <T extends Comparable<T>> OptionalComparator<T> absentLastComparator() {
#SuppressWarnings("unchecked")
OptionalComparator<T> comp = (OptionalComparator<T>) ABSENT_LAST;
return comp;
}
public static void main(String... args) {
OptionalComparator<Integer> absentFirstInt = absentFirstComparator();
System.out.println(absentFirstInt.compare(Optional.of(1), Optional.empty()));
OptionalComparator<Integer> absentLastInt = absentLastComparator();
System.out.println(absentLastInt.compare(Optional.of(1), Optional.empty()));
OptionalComparator<Double> absentFirstDouble = absentFirstComparator();
System.out.println(absentFirstDouble.compare(Optional.of(1.0), Optional.empty()));
OptionalComparator<Double> absentLastDouble = absentLastComparator();
System.out.println(absentLastDouble.compare(Optional.of(1.0), Optional.empty()));
}
Output:
-1
1
-1
1
Guava now provides (since 21.0, and no more #Beta since 27.1) Comparators.emptiesLast(Comparator) and emptiesFirst(Comparator).
Example: Comparator<Optional<Instant>> compareOptInst = Comparators.emptiesLast(Comparator.naturalOrder());
You may just have to do an unsafe cast. Consider how ImmutableList handles the empty-list case:
private static final ImmutableList<Object> EMPTY =
new RegularImmutableList<Object>(ObjectArrays.EMPTY_ARRAY);
/**
* Returns the empty immutable list. This set behaves and performs comparably
* to {#link Collections#emptyList}, and is preferable mainly for consistency
* and maintainability of your code.
*/
// Casting to any type is safe because the list will never hold any elements.
#SuppressWarnings("unchecked")
public static <E> ImmutableList<E> of() {
return (ImmutableList<E>) EMPTY;
}
In this case, it might similarly be easiest to use a raw type instance. As long as you gate all calls that return ABSENT_FIRST with generic casts, this will be fine, and calling code shouldn't have any warnings.

Returning a generic object on Java from abstract class

I have a class that should accept different datatypes as the second constructor parameter:
public abstract class QueryMatch {
String key;
Object input;
public <T> QueryMatch(String key, T o) {
this.key = key;
input = o;
}
public String getKey() {
return key;
}
public Object getValue() {
return input;
}
}
I don't want to use type parameters, like
public abstract class QueryMatch<T>{
String key;
T input;
...
As this way I'm getting raw types warnings when declaring retrieving QueryMatch as a generic (as I don't know the datatype it contains). But the problem is that I need to return the value and I'm not totally comfortable by returning an Object (is that just me, but it doesn't seem like a good practice?).
Additionally, another class inherits from it:
public class QueryMatchOr extends QueryMatch {
public QueryMatchOr() {
super("title", new ArrayList<String>());
}
public void addMatch(String match) {
((ArrayList<String>) input).add(match);
}
}
And of course I'm getting a Unchecked cast warning (which I can avoid with #SuppressWarnings(“unchecked”)).
So, my question is... is there a better way to achieve what I'm trying to do? An abstract class that contains an object (which could be bounded), and returning the datatype it contains (instead of an Object) without using a type parameter in the class declaration?
What you are doing is not a good design. You are using an Object type field from the superclass while you only can know it's actual (needed) type in the subclass. If you only know that in the subclass, declare that variable in the subclass. Not even to mention that your fields are not private.
How about:
public abstract class QueryMatch {
private String key;
public QueryMatch(String key) {
this.key = key;
}
public String getKey() {
return key;
}
public abstract void addMatch(String match);
}
public class QueryMatchOr extends QueryMatch {
private ArrayList<String> input;
public QueryMatchOr() {
super("title");
input = new ArrayList<String>();
}
public void addMatch(String match) {
input.add(match);
}
}
If you need the getValue() method in the superclass, you really should make it generic:
public abstract class QueryMatch<T> {
private String key;
public QueryMatch(String key) {
this.key = key;
}
public String getKey() {
return key;
}
public abstract void addMatch(String match);
public abstract T getValue();
}
public class QueryMatchOr extends QueryMatch<ArrayList<String>> {
private ArrayList<String> input;
public QueryMatchOr() {
super("title");
input = new ArrayList<String>();
}
public void addMatch(String match) {
input.add(match);
}
public ArrayList<String> getValue(String match) {
input;
}
}
So first, I think the best answer is to make your class generic. But if you really don't want to do this you could do something like this:
public <T> T getValue(Class<T> type) {
return (T)input;
}
In some way you need to provide the expected type for the return value to the class. This can either be done my making that class generic or the method generic.
So, my question is... is there a better way to achieve what I'm trying to do?
No, there isn't.
I think you should use generics instead of #SuppressWarnings(“unchecked”))

What method signature is appropiate returning a generic object?

What should be the signature of a method that takes a generic object and returns another generic object, one that either is the same or a sub class of the original class? That is, if the method takes some generic class A, the returned object is guaranteed to be either A or B such that B extends A (directly or indirectly)?
The code below exemplifies what I'm trying to do, in the function getList():
package com.company;
import java.util.ArrayList;
public class Main {
private Main(){
List<String> stringList = new GenericMessageListCreator.getList(StringGenericMessage.class);
}
private class GenericMessageListCreator() {
public List<GenericMessage<T1>> getList(Class<T1 extends GenericMessage> clazz) {
return new ArrayList<T1>();
}
}
private class GenericMessage<T> {
public GenericMessage(){};
private T internalValue;
public void setValue(T value) {
this.internalValue = value;
}
public void echoValue() {
System.out.println("I contain " + internalValue);
}
}
private class StringMessage extends GenericMessage<String>{}
private class IntegerMessage extends GenericMessage<Integer>{}
}
Example aside, in actuality I'm writing a registry of classes that are used for Commands in a command pattern. When I get an object by its class I want to fetch the appropriate Command and pass the object to it.
I think you are looking for this signature:
public <T1 extends GenericMessage> List<GenericMessage<T1>> getList(Class<T1> clazz) {
return new ArrayList<T1>();
}
You'll find more info about generic methods here.
EDIT
Based on what I understand from your sample code, I would go for something like (I corrected some syntax errors in your code):
private class GenericMessageListCreator {
public <U, V extends GenericMessage<U>> List<U> getList(Class<V> clazz){
return new ArrayList<U>();
}
}
private class GenericMessage<T> {
public GenericMessage(){};
private T internalValue;
public void setValue(T value)
{
this.internalValue = value;
}
public void echoValue() {
System.out.println("I contain " + internalValue);
}
}
private class StringMessage extends GenericMessage<String>{}
private class IntegerMessage extends GenericMessage<Integer>{}
Thus, you'll be able to create a List<String from `StringMessage like this:
List<String> stringList = new GenericMessageListCreator().getList(StringMessage.class);
I'm not even sure which method you want to have this behavious on, but I've assuming it's getList():
private class GenericMessageListCreator() {
public <T extends GenericMessage<?>> List<T> getList(Class<T> clazz) {
return new ArrayList<T>();
}
}

Categories