How to find a field of an object using a Generic method? - java

I have a Cube object with a public 'x' field. I have a toString method in my Cube class which prints out the x,y,z fields, but when I directly access it, I get an error where: field cannot be resolved or is not a field.
public <T> void setPosition(T object){
System.out.println(object);
System.out.println(object.x); // error here
}

I would recommend defining an interface that declares the method that your multiple different types will expose. Something like:
public interface ValueProducer {
public String getValue();
}
Then, your Cube type would look like this:
public <T extends ValueProducer> void setPosition (T obj) {
System.out.println(obj);
System.out.println(obj.getValue());
}
Then any type with which you wish to use this method need only implement the interface ValueProducer, and can still extend or implement whatever other types are appropriate for their use cases.
Or, you could omit generics altogether, and just pass obj in as a ValueProducer.

your method does not know what is the type T.
But we can say T is some class which extends
public class GenericCube {
public String value;
}
So, now we able to access the value because we know about it
public <T extends GenericCube> void setPosition(T obj){
System.out.println(obj);
System.out.println(obj.value);
}

I found that I could access the field utilizing Reflection methods and cast to the object I needed. This is supported using an abstract class with this field so that all objects inheriting from this object can utilize this function.
public <T> void setPosition(T object) {
Field xField = object.getClass().getField("x");
Field boxField = object.getClass().getField("boundBox");
float xpos = (float)xField.get(object);
BoundingBox box = (BoundingBox)boxField.get(object);
}
I'm open to critique, but this has been working very well with my multiple classes inheriting from my abstract base class. The reason for this method, is for another class to work with these other classes without creating multiple functions, thus giving flexibility for a user who wants to create their own classes inheriting from the abstract class.

Related

How can I override a method returning a List containing instances of subclass to the class the original methods List contained?

I realize the title is kind of messy, but that's the best I could come up with.
Below is a minimal example of what I wish, but am currently failing to do.
public class ObjectA {}
public class ObjectB extends ObjectA {}
public interface HandlerInterface<T extends ObjectA> {
public T easyToOverride();
public List<T> hardToOverride();
}
public class HandlerA implements HandlerInterface<ObjectA> {
public ObjectA easyToOverride() {
return new ObjectA();
}
public List<ObjectA> hardToOverride() {
return new ArrayList<ObjectA>();
}
}
public class HandlerB extends HandlerA implements HandlerInterface<ObjectB> {
/*
This method ovverides its super method with ease since its return
type directly inherits from the super class's return type
*/
public ObjectB easyToOverride() {
return new ObjectB();
}
/*
This method is NOT accepted by the Java syntax since List<ObjectB>
does NOT directly inherit from List<ObjectA>
The method signature for hardToOverride() clashes with the signature
in the super class and is not overridden because the return types
don't obviously inherit each other
*/
public List<ObjectB> hardToOverride() {
return new ArrayList<ObjectB>();
}
}
Ignore that these classes should be in their own files and that I have not included their imports. I just put it like this to make it easier to read.
As you may have understood by the comments in the class HandlerB, the method hardToOverride() is not accepted (throw this code into your IDE and watch it scream).
I realise I could just return a List<Object> and type cast the contents of the returned List object to the type that I personally know the specific handler instance returns (ObjectA or ObjectB), but that would mean that anyone using these methods has to understand the inner workings of them, and I do not like that.
What I want is to be able to override the List<ObjectA> hardToOverride() method with a method List<ObjectB> hardToOverride() without losing the hard typing that these methods provide.
So my final question is:
Is there any way to keep all of these interfaces, inheritances and overrides without loosing the strong typing they provide in my example code?
If not, what is a better way to achieve a similar set of classes and interfaces that actually works?
Your code is accepted if you declare HandlerA with a new generic even if this is never used really:
public class HandlerA<T> implements HandlerInterface<ObjectA> {
//....
}
NOTE: This is to be considered just a workaround but as result your example code will work as you asked. Moreover, even if HandlerA declares a generic, you can anycase instantiate it also without brackets:
ObjectA objectA = new HandlerA();

Java, force implementation of method without knowing parameters

I have an abstract class that performs basic operations, now I want to force every derived class to have a method "check", but the point is I know nothing about this method. For example, the abstract class:
public abstract class Service<T extends Transport> {
public T getTransport(int id) {
[...]
}
public abstract boolean checkTransport(T transport, ...);
}
and two implementing classes:
public ServiceAAA extends Service<ClassA> {
public boolean checkTransport(ClassA t) {
[...]
}
}
public ServiceBBB extends Service<ClassB> {
public boolean checkTransport(ClassB t, Integer value, Integer otherValue) {
[...]
}
}
The ServiceBBB needs two parameter to check the object t of class ClassB.
Of course it's not working, is there a way to force the subclass to implement the checkTransport method without using the "Object ... " notation?
No, there isn't.
Let's pretend there were a way. How would you invoke this method, either from the abstract Service class, or from any call site that had a reference to this object typed as Service<...>? There'd be no way of knowing what the specific subclass's method expects, and thus no way of invoking the method.
One way around this is to pass the checker in as a class to Service; that is, to use composition instead of inheritance. If you do that, you can have the checker's interface take no extra arguments at all (a Predicate might work, for instance), and the specific subclasses that implement that checker could have the arguments passed at construction time.

how to implement a interface method in Java

When the below code is compiled the compiler shows an error:
InterfaceTest.java:19: error: cannot find symbol knightObj.dispBK();
public class InterfaceTest{
public static interface Knight{
public void embark();
}
public static class BraveKnight implements Knight{
private int id;
public BraveKnight(int id){
this.id = id;
}
public void dispBK(){
System.out.println("ID: "+id);
}
public void embark(){
System.out.println("ID: "+id);
}
}
public static void main(String[] args){
Knight knightObj = new BraveKnight(101);
knightObj.dispBK();
}
}
What may be the possible cause?
Knight is your interface, it does not define a method called dispBK(). Your knightObj object is of type Knight, so you need to cast it to BraveKnight to be able to call the dispBK() method.
Alternatively you could add the dispBK() method into your interface.
Your third option is to initialize your object like this: BraveKnight knightObj = new BraveKnight(101);.
I warmly recommend using some IDE such as Eclipse, they will catch easy errors like this.
As stated in the documentation:
When you define a new interface, you are defining a new reference data
type. You can use interface names anywhere you can use any other data
type name. If you define a reference variable whose type is an
interface, any object you assign to it must be an instance of a class
that implements the interface.
dispBK() is method of class.
& Knight is interface and method is not declared in interface so you can't.
add :
public void dispBK(); in your interface and then it will work.
An Interface reference can hold Object of IMPL if only that all methods declared in interface.
OR you ll have to access that method using Impl object.
Add public void dispBK() to interface and then you can implement it
Method from child is not visible to parent. Here knightObj is an instance of parent interface Knight and you are trying to invoke a method of its child which is not visible. You should either add that dispBK() method to Kinght interface or use casting like ((BraveKnight)knightObj).dispBK();
An interfaace defines the minimum set of methods that the concrete class has to implement. That way you know that if you have a range of Knight objects (such as BraveKnight, CowardlyKnight and GoodKnight) they must all define the embark() method.
If you define your KnightObj variable as the Knight interface, then the methods of Knight are the only ones that are directly accessible.
However, you have instantiated your KnightObj as a new BraveKinght(101), this means that you can still access the additional methods of BraveKnight, if you cast your variable using
(BraveKnight)KnightObj.dispBK();
More detailed EXAMPLE:
You use this when passing parameters to functions or inside arrays, collections, such as
ArrayList<Knight> allKnight = new ArrayList<Knight>();
allKnight.add(new BraveKnight(105));
allKnight.add(new CowardlyKnight(13));
allKnight.add(new GoodKnight(88));
To test which concrete class you actually have, you use instanceof to evaluate it, ie
for (Knight eachKnight : allKnight) {
// No need to cast this, as all Knightly objects must implement it.
eachKnight.embark();
if (eachKnight instanceof BraveKnight) {
(BraveKnight)eachKnight.dispBK();
} else if (eachKnight instanceof CowardlyKnight) {
(CowardlyKnight)eachKnight.runaway();
} // no test for GoodKnight - he's always good
}

Abstract method with variable list of arguments

I haven't quite found an elegant way to solve this issue. I have an abstract class that several other classes are inheriting with an abstract method that can contain anywhere from zero to 4-5 arguments of varying types.
public abstract class Item {
public abstract void use();
}
For instance, I have a Book class that inherits this and takes no arguments when overriding use(), I have a Key class that inherits and takes a String and a Queue as arguments when overriding, etc...
I've tried using generics but I have to input the number used, such as Item, when it actually depends on the class.
public abstract class Item<T,U> {
public abstract void use(T arg1, U arg2); //Number of arguments/types could be more or less
}
I've tried sending a variable list of Objects but the object types are always variable and I've unsure as to the syntax to receive in the inheriting classes.
public abstract class Item<T> {
public abstract void use(T... arguments);
}
public class Book extends Item<?> {
public void use(?);
}
public class Book extends Item<String, Queue> { //Wrong number of arguments since I can't use Item<T...>
public void use(String str, Queue q); //fails
}
I may just be doing something wrong - can anyone offer any assistance or insight?
I've struggled with the same question, and there's not a perfect answer, but I can give you a few things to consider. First, you're basically trying to do something that is inherently against Object Oriented Programming, which is that you're trying to create a variable interface. The point of an interface is that code that gets an abstract version of the object (the Item rather than the Book, for example), knows how to invoke the use() method. This means that they must know what can be passed to the use() method. If the answer depends on the implementation of the abstract class or interface, then you need to ensure that the code using it actually knows what kind of implementation (Book, etc.) that it's using, otherwise it's not going to know how to invoke use() with the appropriate parameters anyway. It sounds like you need to refactor your code, in all honesty.
However, there is a way to answer your question as stated without refactoring the architecture. You could create a class that's data is all of the different types of parameters that could possibly be passed to the use() method, have the calling code set the fields of that class, and then pass that to the use() method. For example:
public class UseParameters {
private String string;
private Queue queue;
// Any other potential parameters to use(...)
public void setString(String string) {
this.string = string;
}
public String getString() {
return string;
}
// All of the other accessor methods, etc.
}
Then, you could define the use method in Item like this:
public abstract void use(UseParameters params);
And any code using an Item would have to set the parameters of the object appropriately:
Item item = // However you're going to get the item
UseParameters params = new UseParameters();
params.setString("good string");
params.setQueue(new Queue());
item.use(params);
I just want to point out that if the code above knows the Item is a Book (which is how it knows to set the String and Queue, then why not just get a Book and skip needing an abstract class with a variable use() method altogether? But I digress. Anyway, the Book would then implement the use() method like so:
#Override
public void use(UseParameters params) {
if(params.getString == null || params.getQueue() == null)
// throw exception
// Do what books do with strings and queues
}
I think that gets you what you want, but you should consider refactoring, I think.
What you want is the Value Object Pattern.
Define a class that encapsulates the various parameter types into one value object, and have the abstract method accept a parameter of this type. Each variation of parameters you were considering would have its own value class.
Then simply add a generic type to the class and have the abstract method accept a parameter of that type:
public abstract class Item<V> {
public abstract void use(V v);
}
To use it, suppose MyItem needs a value object of type MyValueClass:
public class MyItem extends Item<MyValueClass> {
public void use(MyValueClass v) {
}
}
If the types to be used as argument are always variable I don't see a reason to use generics. Just use plain Object type:
public abstract class Item {
public abstract void use(Object ... arguments);
}
public class Book extends Item {
public void use(Object ... arguments) { ... }
}
The best approach I can think of is to group the items according to the behavior of their use() method.
Example
public abstract class QueueableItem {
public abstract void use(String, Queue);
}
public abstract class OrdinaryItem{
public abstract void use(String);
}
If the grouped items share a common behavior (common as in same method signature & return value), you can define and extend a parent class that will contain the definition of this common behavior.
Yes, we can provide parameters to abstract method but it is must to provide same type of parameters to the implemented methods we wrote in the derived classes.

Java Reflection/Generic

Given the following three classes how can I use reflection to call the initialize function for the parent class(es) and then the subclass:
public class Test {
public static void main(String[] args) {
ExtendedElement ee = new ExtendedElement();
initialize(ee);
}
public static void initialize(Element element) {
System.out.println(element.getClass());
initialize(element.getClass());
}
public static void initialize(Class clazz) {
System.out.println(clazz.getClass());
}
}
public class Element {
protected String value;
public String getValue() { return value; }
public void setValue(String value) { this.value = value; }
}
public class ExtendedElement extends Element {
protected String extendedValue;
public void setExtendedValue(String extendedValue) {
this.extendedValue = extendedValue;
}
public String getExtendedValue() { return extendedValue; }
}
I'm not quite sure on how to paramertize the initialize function in the Test class, as the clazz parameter is a raw type.
What I essentially need is to call initialize up the class hierarchy if what I pass into initialize is of a subclass of Element.
Something like the following:
public void initialize(Class clazz) {
if (Element.class.isInstance(clazz.getClass().getSuperclass()) {
initialize(clazz.getClass().getSuperclass());
}
//Work to call initialize function
}
Edit 1:
Can't I parameterize the above pseudo function differently to retain the type of the object and then call the function I need to?
What I'm trying to do is avoid having to have the same method overridden for each of my classes and allow some inheritance for my Selenium 2 Page Objects. What I need to do is be able to is introspect the superclass(es) of my self and initialize each of my WebElement fields prior to running tests on these fields.
These are being injected with spring, and to further complicate things I am allowing tests to be written using Spring Expression language. I am lazy loading my beans, and using the InitializingBean interface to attempt to initialize my WebElements prior to their usage to avoid NPEs.
I had to wrap the WebElements with a custom object so that I could inject the location strategies using spring (We reuse a lot of pieces, but they have different ids / class names dependent upon where they are used in the application; this was done prior to me getting here and will not be changed at this time despite my arguments for consistency). For example we have a date widget that has different granularities, sometimes we need just a month, sometimes month and year, etc... It'd be nice if I could use an abstract class and break these commonalities down to their least common denominator and extend from there. To do that I need to be able to do the following in my base class:
public abstract class PageObject implements InitializingBean {
...
public void afterPropertiesSet() {
//Pass in concrete impl we are working with - this allows me to initialize properly
initializeWebElements(this.getClass());
}
...
public void initializeWebElements(Class clazz) {
//This does not grab inherited fields, which also need to be initialized
for (Field field : clazz.getDeclaredFields()) {
if (WidgetElement.class == field.getType()) {
Method getWidgetElement = clazz.getDeclaredMethod("get" +
StringUtils.capitalize(field.getName()), new Class [] {});
WidgetElement element =
(WidgetElement) getWidgetElement.invoke(this, new Object [] {});
element.initElement();
}
}
You can't call a method at a specific level. The only thing is you have access to the super keyword inside the class itself.
To make this work, you want to call super.initialize() from within each subclass, then just call it via reflection.
This is not C++, where you can call a specific method at a specific level of the inheritance hierarchy.
I'm not quite sure on how to parameterize the initialize function in the Test class, as the clazz parameter is a raw type.
Nothing in your example requires you to make use of the generic type parameter, so declare it as Class<?>.
I don't understand what your initialize methods are really trying to do, but there are a number of problems:
You seem to have one initialize method that takes an instance (of Element) as an argument, and another that takes a Class object as an argument. That's really apples and oranges stuff ... and you need to explain what you are trying to do.
Your attempt at fleshing out the method contains this:
Element.class.isInstance(clazz.getClass().getSuperclass())
This will never evaluate to true, because it is asking if some Class object is an instance of the Element class. (What is more, clazz.getClass().getSuperclass() is actually going to be the same as java.lang.Object.class. The class of a Class object is java.lang.Class and its superclass is java.lang.Object).
But I can't figure out what it should be, because you don't clearly describe what you are trying to achieve.
Here is my temporary solution, leaving question open to hopefully gather some better answers though for my use case.
public abstract class PageObject implements InitializingBean {
...
public void afterPropertiesSet() {
Class clazz = this.getClass();
do {
initializeElements(clazz);
clazz = clazz.getSuperclass();
} while (clazz != null);
}

Categories

Resources