I want to simplify a project by removing useless classes. By useless classes I mean something like :
public class MainPage extends TileGridFragment<MainModel> {}
The whole logic of this class is implemented by TileGridFragment, and the data is provided by MainModel, which instance is accessed thanks to a singleton class.
I want to defer the instanciation of such class to a later time, so I simply pass MainPage.class to my methods.
As MainPage is equivalent to TileGridFragment<MainModel>, I would like to remove this class and instead use something like TileGridFragment<MainModel>.class instead.
But this doesn't work and I'm out of idead.
I've also tried Class.forName, but its throws a ClassNotFoundException.
Any idea ?
If the implementation of MainPage is actually {}, just pass TileGridFragment.class. The actual type parameters are irrelevant on runtime because they are removed by erasure.
Also, because of erasure, you can cast the new TileGridFragment (with a raw type, as the result of TitleGridFragment.class.newInstance()) to TitleGridFragment<MainModel>, and ther will be no collateral damages (other than a little warning from the compiler, that can be supressed).
You can't really, you might get some joy from reflection but I'm not sure exactly what you're trying to do.
Try here:
Get generic type of class at runtime
Related
My problem is I do have a class that is created, compiled and initialized at runtime. I did this as writing the file as TestClass which is File f,
then compile with:
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null,null,null,f.getPath());
After that I load my class and use my methods etc. according to this example;
http://viralpatel.net/blogs/java-dynamic-class-loading-java-reflection-api/
Now my problem is I need to do this:
MyTask<T> m = new MyTask<T>(0,0,0);
T should be my dynamically created class instead of Integer.class etc. However I couldn't find a way for it yet. If you do examine the example at the link I gave above, you will see I can have a instance of my class as in Object form and I can a Class instance for my dynamic class. However, whatever I tried I couldn't find the solution for this.
It keeps saying that Class myClass, can not be used as a type. So how can I use this dynamically created class as a type. Thank you very much.
There is no useful way to express in source code a type that does not exist at compile time. It would not anyway gain you anything more than using Object as a type parameter could do, because Java generics provide compile-time type checking, not run-time type checking.
It might be that your purposes could be served by creating an interface that your dynamic class will implement, and using the interface type as your type parameter.
You can't due to the fact that the generic type information is available only at compile time. When you create a class at runtime, there's no generic information available anywhere any more.
If your class implements an interface, you should use that as the type in code. Something along the lines of
MyInterface foo = myDynamicClass.newInstance();
someGenericMethod(foo);
public <T extends MyInterface> void someGenericMethod(T param) {}
// Or more likely, if there's no other classes that extend MyInterface
public void someGenericMethod(MyInterface param) {}
Of course it may not make any sense to even bother with generic type information, since it's used for static type checking and you're working with a dynamic class.
Is there anything wrong with extending a generic class just to simplify or prevent writing redundant code?
Basically what I want to do is
class EnityGroup extends LinkedList<Entity>
{
....
}
but every example I've seen composition seems to be preferred.
What, if any, are the issues, concerns, conflicts etc that I would have to worry about.
What you are looking for is a type alias, a feature available in other programming languages (eg. C or C++). Java doesn't provide such feature.
For the type system EntityGroup is-a LinkedList<Entity> so nothing bad can happen. Every method that accepts a LinkedList<Entity> will accept an EntityGroup instance.
The only shortcoming is that the constructors are not directly available to your subclass so you are forced to redeclare them (possibly forwarding arguments to superclass constructor).
From a polymorphic point of view this is not like having a type alias, since EntityGroup is a different type which extends another type, not a different name for LinkedList<Entity>. So LinkedList.class != EntityGroup.class, this could create problems with code that uses reflection, unless written correctly to automatically detects types in the hierarchy.
Inheritance is there to enrich or specialize behavior of a class, which is not the case in this situation. You are basically using a feature to obtain something that is not meant to be obtained in this way, but by having type aliases, which unfortunately aren't available in Java.
This problem comes up quite a bit actually. Take this instance model view. I have 2 objects. Simulation object and render object.
The class ObjectRSim (Object, designated as Render Sim) is something like:
class ObjectRSsim {
var simObject:ObjectSim;
}
ObjectRSim, uses properties/invalidation of ObjectSim.
There are objects that inherit ObjectRSim and ObjectSim:
PosObjectRSim and PosObjectSim (positional objects..)
class PosObjectRSim extends ObjectRSim {
var posSimObject:PosObjectSim;
}
or...
class ObjectRSim {
var simObject:Dynamic; //Dynamic is untyped Type from haxe, the compiler does not check calls to a Dynamic object.
}
Should I have a reference to each type in the inheritance hierarchy of ObjectSim in the ObjectRSim hierarchy classes, or should I just use simObject:Dynamic?
It will be totally wrong to use Dynamic for that case. It's frequently slow(for every haxe target except javascript I guess), not inlined, and is normally used only for interacting with underlying platform or working with serialization(YAML, JSON etc.).
Talking about solving the problem...
If there aren't thousands of this objects planned, I'd probably just another field for lower-level class object. It's not the clearest way from OOP perspective, but it frequently results in simpler and clearer code for me.
Casting is another option(I personally don't like).
Parameterization would probably be the best way to handle that, but I'm not sure if we already have type restricted parameterization in haxe.
Parameterize the dependent class and the dependency member.
Is there a way to specify a default type for a generic template?
Let's say I have a Monkey class. Monkeys can live in different Environments, such as Jungle or Zoo:
public class Monkey<T extends Environment>
{
T home;
...
public T getHome()
{
return home;
}
}
Is there a way to specify a default for T, so I can use the type Monkey instead of Monkey<?> without getting a compiler warning?
EDIT
In other words, is there a way to get rid of the "raw type" warning without having to explicitly suppress it?
No, you can't do that. Generic parameters don't have default values. You could re-organize your type hierarchy so that there's a GenericMonkey and a DefaultMonkey that sets the generic parameter to your desired default.
No you can't:
http://en.wikipedia.org/wiki/Comparison_of_Java_and_C%2B%2B
Generic type parameters cannot have default arguments.
What about making something like this:
public class Monkey extends Monkey<YourType>
Obviusly you'll "waste" the ability to inherit.
EDIT 1:
Another interesting thing is do the reverse of what I suggested,
public class Monkey<T> extends Monkey
In this case all generics class Monkey inherits Monkey, in some cases, this is a very interesting thing (expecially when you notice that some instance-methods fits in all classes without requiring the generic). This approach is used in Castle ActiveRecord (I've seen it used in C#, not in Java), and I find it beautiful.
Jen, your question doesn't put any context around why you want to use a generics. It would really be helpful if you stated what it is you are trying to do and why you are using generics. Generics exist IMHO mainly to avoid having to do class casts everywhere when putting things into and taking them out of collections that are designed to be generic holders of types. This kinda implies iteration over a bunch of things, but not necessarily.
My point is, I didn't see any part of your class or code that required being able to create a custom version of the monkey class that required iterating over environments. If this is not the case, you probably don't even need generics. Instead, you probably want dependency injection. The monkey class should have a constructor that takes an environment. Environment is an interface (or simple base class). The interface has several default operations like getBathroomLocation() and getFoodLocation(). Instead of using generics to create a type of monkey that lives in the zoo, you create a monkey and inject the dependency of which environment it lives in.
Monkey monkey = new Monkey(new CostaRicaJungle());
Later on, you can set this environment to something different. The wild monkey gets captured, and you now do
monkey.setEnvironment(new BronxZoo());
Later, the monkey gets an living condition upgrade, and you do a
monkey.setEnvironment(new SanDiegoZoo());
Why not just use the base class of the Generic? Monkey<Environment> ?
(This is somewhat a followup to my previous question)
I've got a Foo<?> object, foo. Foo<T> is an interface.
How to get the type value hidden behind the <?>?
Note that this is not trivial, as foo can be for example an object of class Bar<String>, where Bar<T> implements Foo<T>, or some anonyomus class implementing interface FloatFoo, where FloatFoo extends Foo<Float>. I need a solution that works in all cases.
Thanks in advance :)
This is not possible using reflection because Java Generics has the problem of Type Erasure. At runtime the types that have been defined for the generic class Foo have been removed, so using reflection on that class will not yield its generic type. This type information is used only in compilation for type safety.
C# does not have this issue and it is possible to access the templatized type of a Class.
This is a overview of the differences.
Well, for short, you can't.
However, what you can do is get the value of <?> when using FloatFoo.
Indeed, from what I remember, generics are not kept in class information.
however, when you create a subtype (be it class or interface) of a generics type, the generics information has to be memorized as it may define some of the subtype's methods signature.
As an example, if your Foo interfaceis declared as it :
public interface Foo<T> {
public T doIt();
}
Having a
public interface FloatFoo extends Foo<Float>
implies this interface has a
public Float doIt();
method declared.
For that, the compiler has to have the type information. And this information will be reflected in the reflection API by the fact that FloatFoo's super class will have some Type parameters associated to it. Or it least it is what I remember from the few cases I encountered such cases (or elaborated them, as it may sometimes be mandatory)
But you'll have far more complete informations at Angelika's generics FAQ.
The final-final (and perhaps the best possible) solution: I refactored my code, so it doesn't need this. I moved all code which needed the type parameter into Foo, so I could provide appropriate implementation within the class. It turned out to be much less code.
I ended up with creating a getType() method in the interface:
Class<T> getType();
Maybe it's not the most elegant solution, but definitely the simplest one.