Using methods with returned jcomponents and generics - java

This is a two part question. First, is it possible use a generic defined objects method such as:
public class MyClass<T>{
public MyClass(T t){
t.setText("Hello World"); // Assume class T is JMenuIten has the special method setText
}
}
This code doesn't work as is, but show the general idea for what I'm aiming for. I want to use the methods which are particular to that encapsulated object. If however I were to pass in another object such as which contains the encapsulated method .doSomething. I would like to do ...
public class MyClass<T>{
public MyClass(T t){
t.doSomething("Hello World"); // Assume class T is JMenuIten has the special method setText
}
}
I'm hoping that it is possible to do this, otherwise I would have to write multiple constructors to take care of all my special cases.
My second question is similar in that I would like to return a GUI component and execute a statement such as ...
myJPanel.getComponent(1).setText("Hello"); // Assuming index 1 is a JLabel and setText is a specific method defined in the JLabel class
This code does not work because the compiler cannot tell ahead of time what symbols will be needed at runtime, though I was hoping that there was a way of making things like this work. I would also like to know if there is a method that can tell me what class type .getComponent() is returning if that is possible. I'm trying to make code as dynamic as possible without having to hardcode everything.
Thanks

You have to use a bounded wildcard.
e.g.
public interface MyObject {
void myMethod();
}
public class GenericObj<T extends MyObject> {
private T t;
public void invokeMethod() {
t.myMethod(); //this way you can invoke methods (declcared in MyObject) on T
}
}

Related

Is using method reference bad for performance?

I need to build my own library to handle events coming from an event bus, the first solution I came up with was an abstract class made like this one:
public abstract class MyEventListener<T> extends RealEventListener{
private final Class<T> type; //the event class type
private final String stream; //the stream
public abstract onEvent(T type); //the method my subclasses have to implement
#Overrides
public void onEvent(byte[] evt){ //takes the original, clunky method and evolves it with typing
//convert and do stuff
onEvent(convertedEvent); //call method
}
}
so, the classes only do:
#Component
public class Child extends MyEventListener<AType>{
public Child(){
super(AType.class, "stream"); //registers
}
#Overrides
public void onMessage(AType evt){ //do stuff
}
I find this approach somewhat limiting and outdated (at least seeing the latest libraries). An example I can think of is that, this way, you are forced to handle separate events in separate classes.
So, I though of using annotations to have something like this:
#EventListener("stream") //1. you define the stream in this custom class annotation
public class Child { //so no need to extend
#ListenTo(type=AType.class) //2. you define the type on methods, this way a single class can handle more
public void onMessage(AType event, //any other param){
}
Now, for the magic behind, I though about using a startup annotation processing to retrieve the methods:
public void initialize(#EventListener List<Object> listeners) { //I inject all objects
listeners.stream().map(..).collect(..) //use reflection to get all methods annotated with #ListenTo and put them inside of map <String, Method>
eventBus.registerListener(new MyEventListener(target, methodMap)); //
}
Now, the listener will take somewhat the type from the original byte event and call the method:
String className = getClassFromEvent(evt);
listenerMap.get(className).invoke(target, evt);
According to you is this approach valid and, most importantly, efficient? Or, excluding the initialization phase, it could lead to performance problems at runtime? Of course I should make static checks at initialization to make sure that the annotated methods declare the event as parameter but it seems cleaner to me than the first one.

Call method once after any one of a few overloaded methods are called

In an abstract class I have a Predicate field, that is meant to be a combination of an unknown number of other Predicates. Joining the predicates works just fine but I am trying to have some way to know when the predicate has been initialized (or rather, just a way to know if it has or hasn't been initted).
Here is a short example of what I'm talking about:
public abstract class LimitedSystem implements Moveable {
private Predicate<Double> limits;
private final boolean initialized;
public void setLimits(SingleLimit... limits) {
List<Predicate<Double>> limitsList = Arrays.asList(limits);
this.limits = limitsList.stream().reduce(Predicate::and).orElse(x -> true);
}
public void setLimits(TwoLimits limits) {
this.limits = limits;
}
...
I am looking for ways to set initialized to true once (and once only, hence the final. I think I used it right) any of the setLimits have been called (they're overloaded).
I have other setLimits methods, but for the sake of generic code, I don't want to put a initialized at the end of each of the overloaded methods.
So my question is how can I, in a generic way, set the value of initialized after any of the setLimits methods has been called.
My first idea was to try to wrap the setLimits in some generic method which would call the correct overload by the parameter it gets, and then change initialized in that method. But I am not sure if that's a good idea.
Some other idea I got from another question1 was to put the setLimits in some interface or something similar. But I'm not sure how useful that might prove.
So how might this be accomplished?
(Also, if you happen to notice any design problems in this, please tell me because I'm trying to improve in that matter)
There's no need for separate fields:
private Predicate<Double> limits;
private final boolean initialized;
is basically
private Optional<Predicate<Double>> limits = Optional.empty();
if you want initialized to be set to true once limits is set,
provided you can guarantee that none of the setLimits methods can set it to Optional.empty() again. initialized == limits.isPresent().
You can't guarantee that a method is called in the body of an overridden method; in any case, this is a variant of the Call super antipattern.
You can do it like this:
abstract class Base {
final void setFoo(Object param) { // final, so can't be overridden.
setFooImpl(param);
thingThatMustBeCalled();
}
protected abstract void setFooImpl(Object param);
final void thingThatMustBeCalled() { ... }
}
class Derived extends Base {
#Override protected void setFooImpl(Object param) { ... }
}
But it's pretty ugly.

Delegate method calling in Java

In Java: What is the best way to pass a method from one object to another so that it can be called at a later time by the second object?
I come from an ActionScript background where it is as easy to pass around references to methods as it is to pass around references to variables but this seems to be much more difficult in Java. The first few links I found flat out say it is not possible (and it may have been at the time of their posting), but then I found http://www.javacamp.org/javavscsharp/delegate.html which details how this can be accomplished.
My issue with using Javacamp's example is the string based reference to the method. Methods get renamed all the time and a string reference will only complain once you actually run that function runtime as opposed to compile time for a proper explicit link.
Is there no way to do this with proper explicit links to the method you want the other class to execute?
Model of what I am hoping to accomplish:
Player clicks an upgrade button on Activity1 > Activity1 passes upgrade method to a new confirmation activity
Player clicks "Yes" > Confirmation activity calls upgrade method passed in from Activity1
OR: Player clicks "No" > Confirmation Activity closes
EDIT:
To be clear I am not looking for a static method solution as that would require my Confirmation activity to hold many lines of logic for which static method to call. The Confirmation activity will be used all over my application: a simple "Are you sure you want to X?" -Yes -No, if yes execute X
I am currently looking at implementing onActivityResult to avoid this issue but that will be more logic than I like for this kind of issue.
you can use interfaces like this:
public interface MyMethod {
public void method();
}
public class FirtObject{
private SecondObject ob;
public void tellSecondObjectExecuteLater(){
ob.executeLater( new MyMethod() {
public void method(){System.out.println("duh Method");} });
}
}
public class SecondObject {
private MyMethod myMth;
public void executeLater(MyMethod mth){
myMth = mth;
}
public void executeNow(){
myMth.method();
}
}
does this solve your problem?
The typical way to pass methods is to use an Interface and Anonymous Inner Classes. In order to maintain static typing an Interface is used to declare the method signature and typing information. The caller can use either a concrete implementation of that interface as a normal class or using Anonymous Inner Classes for quick class creation. I'll use standard Java SDK classes to illustrate:
interface Comparator<T> {
public int compare( T a, T b);
}
class SpecialCollection<T> {
public void sort( Comparator<T> comparator ) {...}
}
public class SomeClient {
public void doSomething( SpecialCollection<SpecialObj> collection ) {
collection.sort( new Comparator<SpecialObj>() {
public int compare( SpecialObject a, SpecialObject b ) {
// some implementation
}
} );
}
}
The above is an example of a strategy pattern. The thing about the strategy pattern (and passing callback methods like in Javascript). The author has to plan for those types of extensions. The author has to predict up front where he/she wants you to extend. And it just happens it's cleanest if you use Interfaces.
However, pure delegation doesn't have to have always involve Interfaces. You can pass concrete classes, since Java can always pass a subclass that overrides various methods of that class to change what method or code will be invoked. For example in Java InputStream/OutputStream are abstract classes and you typically pass subclass instances to the methods.
If you need the method to act differently depending on the context (AKA, it is different depending on how it is created), you'll want to pass along the instance of the class that the method is in.
If it is a static method, you can just referenced the method itself if you import that class at the top of your new class.
For example, lets say you have a method that will tell you stuff about a certain string. IF the class looks like this:
class stringChecker {
private String stringToCheck;
public class stringChecker(String s) {
stringToCheck = s;
}
public int getStringLength() {
return stringToCheck.length();
}
public boolean stringStartsWith(String startsWith) {
return (stringToCheck.indexOf(startsWith) == 0);
}
}
Then you'll want to pass along the instance, since it is non-static. Different instances have different strings that they were created with, so you will get a different return if you use a different instance.
However, if your class looks more like this:
class stringChecker {
public static int getStringLength(String s) {
return s.length();
}
public static boolean stringStartsWith(String s, String startsWith) {
return (s.indexOf(startsWith) == 0);
}
}
Then you can just reference those methods with stringChecker.getStringLength("test");, because the methods are static. It doesn't matter what instance they are in. The returned result depends ONLY on what is being passed in. You just have to make sure to add import stringChecker; at the top or whatever your class will be called. For you, it'll probably be something like com.example.blah.otherthing.stringChecker, since you're working with android.
Good luck! I hope this helps :)
EDIT: Looks like I may have read the problem too quickly...if this isn't what you were asking about, just let me know with a comment and I'll delete this answer so as to not confuse anybody else.
You said that you are using it in a project to open a Confirmation activity.
Activities should not contain references to each other to avoid memory leaks. To pass data between activities should be used Intent class. To receive a result, call StartActivityForResult() and get result in the onActivityResult() method.
But in general for your task is more suitable AlertDialog or PopupWindow.

Subclass-specific override in Java

My problem is as follows:
We have an Algorithm that works internally with
Expression-objects that have a "String getContent()" method
Manipulator-objects that manipulate on Expressions using the "Expression manipulate(Expression e)" method
This will become a framework in Java.
To solve a real problem, one needs to give a specific implementation
of both an Expression and a Manipulator and the Algorithm class will do the rest.
Let's say we need a ProblemExpression and a ProblemManipulator
for a specific problem.
The ProblemExpression may contain a lot of new fields,
which can be used by the ProblemManipulator.
Right now, I can only think of two ways to write clean code:
Let ProblemManipulator.manipulate assume its arguments are ProblemExpressions
Use instanceOf
But I've got the feeling this is not how I should do it.
Any other suggestions?
Regards and thank you in advance,
Xaero.
Sounds like you should use a Generic. Like
interface Manipulator<E extends Expression> {
public void manipulate(E expression);
}
class ProblemManipulator implements Manipulator<ProblemExpression> {
public void manipulate(ProblemExpression expression) {
// expression is a ProblemExpression
}
}
As "Problem" is a different problem, it can be an interface that extends Expression like so:
interface IProblemExpr extends Expression
{ //additional methods
}
class ProblemExpression implements IProbExpr
{
}
class ProblemManipulator()
{
ProblemManipulator(IProblemExpr expr)
{
..
}
}
Generics are not enough, if both ProblemExpresions and ProblemManipulators can be accessed publicly.
At first i thought some kind of factory framework would do the trick.
I.e., either Expressions need to be able to create Manipulators or vice-versa.
for example, say ProblemManipulators were private inner classes of ProblemExpressions - obtained from Expression#createManipulator(...).
However, this does not quite do the trick ... in the end, if the Algorithm is allowed to 'hold onto references to' both the Expression and Manipulator, and can obtain different unrelated implementations, then the Algorithm implementation can always (if incorrectly written) wind up invoking the wrong Manipulator for a given Expression - nothing can be done at compile time to prevent this runtime mistake as all Manipulators can be invoked with any Expression.
So, it seems to me that invocation of the Manipulator (or Expression) must 'go thru' the Expression (or conversely the Manipulator) thus ensuring that the correct Manipulator is invoked for the given Expression.
I.e., Expression needs 'manipulate()' method which delegates to the appropriate Manipulator.
I studied the way generics work, and I came up with the following solution:
First, I created a two classes, one for the expression and one for the manipulator:
public class ObjectExpression { }
public class ObjectManipulator <E extends ObjectExpression> {
public void calculate(Set<E> objects) {
... // Do something
}
}
Next, I created an Algorithm class, which is generic.
Two classes are needed:
Some expression
Something that manipulates this type of object
We get:
public class Algorithm <F extends ObjectExpression, E extends ObjectManipulator<F>> {
E om;
public Algorithm( E om ) {
this.om = om;
}
public void run(Set<F> objects) {
om.calculate(objects);
}
}
Then, I created an implementation for the String case:
we need an expression and a manipulator
public class StringExpression extends ObjectExpression {
}
public class StringManipulator extends ObjectManipulator<StringExpression> {
#Override
public void calculate(Set<StringExpression> objects) {
// Do String stuff
}
}
Then, we can run the Algorithm as follows for Objects:
Algorithm<ObjectExpression, ObjectManipulator<ObjectExpression>> algo1 = new Algorithm<ObjectExpression, ObjectManipulator<ObjectExpression>>(manipo);
Set<ObjectExpression> objects = new HashSet<ObjectExpression>();
... // fill set
algo1.run(objects);
And for Strings:
StringManipulator manips = new StringManipulator();
Algorithm<StringExpression, StringManipulator> algo2 = new Algorithm<StringExpression, StringManipulator>(manips);
Set<StringExpression> strings = new HashSet<StringExpression>();
... // fill set
algo2.run(strings);
To me, this seems an elegant solution.
What do you think?
Any alternatives/improvements?

Is it possible to do computation before super() in the constructor?

Given that I have a class Base that has a single argument constructor with a TextBox object as it's argument. If I have a class Simple of the following form:
public class Simple extends Base {
public Simple(){
TextBox t = new TextBox();
super(t);
//wouldn't it be nice if I could do things with t down here?
}
}
I will get a error telling me that the call to super must be the first call in a constructor. However, oddly enough, I can do this.
public class Simple extends Base {
public Simple(){
super(new TextBox());
}
}
Why is it that this is permited, but the first example is not? I can understand needing to setup the subclass first, and perhaps not allowing object variables to be instantiated before the super-constructor is called. But t is clearly a method (local) variable, so why not allow it?
Is there a way to get around this limitation? Is there a good and safe way to hold variables to things you might construct BEFORE calling super but AFTER you have entered the constructor? Or, more generically, allowing for computation to be done before super is actually called, but within the constructor?
Thank you.
Yes, there is a workaround for your simple case. You can create a private constructor that takes TextBox as an argument and call that from your public constructor.
public class Simple extends Base {
private Simple(TextBox t) {
super(t);
// continue doing stuff with t here
}
public Simple() {
this(new TextBox());
}
}
For more complicated stuff, you need to use a factory or a static factory method.
I had the same problem with computation before super call. Sometimes you want to check some conditions before calling super(). For example, you have a class that uses a lot of resources when created. the sub-class wants some extra data and might want to check them first, before calling the super-constructor. There is a simple way around this problem. might look a bit strange, but it works well:
Use a private static method inside your class that returns the argument of the super-constructor and make your checks inside:
public class Simple extends Base {
public Simple(){
super(createTextBox());
}
private static TextBox createTextBox() {
TextBox t = new TextBox();
t.doSomething();
// ... or more
return t;
}
}
It is required by the language in order to ensure that the superclass is reliably constructed first. In particular, "If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass."
In your example, the superclass may rely on the state of t at construction time. You can always ask for a copy later.
There's an extensive discussion here and here.
You can define a static supplier lambda which can contain more complicated logic.
public class MyClass {
private static Supplier<MyType> myTypeSupplier = () -> {
return new MyType();
};
public MyClass() {
super(clientConfig, myTypeSupplier.get());
}
}
The reason why the second example is allowed but not the first is most likely to keep the language tidy and not introduce strange rules.
Allowing any code to run before super has been called would be dangerous since you might mess with things that should have been initialized but still haven't been. Basically, I guess you can do quite a lot of things in the call to super itself (e.g. call a static method for calculating some stuff that needs to go to the constructor), but you'll never be able to use anything from the not-yet-completely-constructed object which is a good thing.
This is my solution that allows to create additional object, modify it without creating extra classes, fields, methods etc.
class TextBox {
}
class Base {
public Base(TextBox textBox) {
}
}
public class Simple extends Base {
public Simple() {
super(((Supplier<TextBox>) () -> {
var textBox = new TextBox();
//some logic with text box
return textBox;
}).get());
}
}
That's how Java works :-) There are technical reasons why it was chosen this way. It might indeed be odd that you can not do computations on locals before calling super, but in Java the object must first be allocated and thus it needs to go all the way up to Object so that all fields are correctly initialized before you can modify them.
In your case there is most of the time a getter that allows you to access the parameter you gave to super(). So you would use this:
super( new TextBox() );
final TextBox box = getWidget();
... do your thing...

Categories

Resources