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> ?
Related
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.
Assume I find something lacking in the default base class Object, and write a class of my own to use instead.
class MyObject extends Object
{
...
}
Is there a way to tell the Java compiler to use my new class as base class instead of the Object class?
Thus avoiding
class MyClass extends MyObject
and just go
class MyClass
and have it implicitly extend MyObject using, say a command line parameter to the compile
javac MyClass --defaultBase=MyObject
That would mean that all Jars and pre-compiled Class-files would use Object, but anything I compile myself would use my own class, except of course, my new base class. (I wouldn't want a circular dependency, would I.)
You can change the Object class within many limitations, but that not really a good idea. The best solution is to create your own class you want other classes to extend.
If you want to extend Object, the best option is to create a Utility method which takes an Object as an argument.
Is there a way to tell the Java compiler to use my new class as base class instead of the Object class?
No. You can't.
The Java Language Specification (JLS 4.3.2) states that the java.lang.Object class is a superclass of all other classes. If a compiler didn't implement that, it wouldn't be a compliant Java compiler. At any rate, I know of no Java compiler ("compliant" or not) that does allow you to do this.
#Peter Lawrey mentions that it is possible to change the Object class. This is true ... if you know what you are doing. But there are dependencies on internal details of the Object class hard-wired into other class ... and the native code implementation of the JVM. If you change some things (for example, adding instance fields or changing method signatures) you are liable to break the JVM, tools in the Java tool-chain, and/or 3rd-party libraries and tools (like your favourite IDE!). The breakage is liable to be castrophic, and difficult to diagnose.
On top of that, if your change doesn't break Java, you are still stuck with the problem that a real JVM won't run your code. That makes monkeying with Object a viable proposition for "research purposes only" ... at best.
For the record, it is technically possible to override the core classes of the the Java runtime library using the -Xbootclasspath VM option(s) (type java -X to get the info). However, this is not intended to be done by a usual developer (see other answers to this question).
You can try it yourself by modifying and compiling the source of the java.lang.Object to a directory named core-classes, for example, and passing the -Xbootclasspath/p:core-classes as a JVM argument.
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
In my quest to correctly grasp Interface best practices, I have noticed declarations such as:
List<String> myList = new ArrayList<String>();
instead of
ArrayList<String> myList = new ArrayList<String>();
-To my understanding the reason is because it allows flexibility in case one day you do not want to implement an ArrayList but maybe another type of list.
With this logic, I set up an example:
public class InterfaceTest {
public static void main(String[] args) {
PetInterface p = new Cat();
p.talk();
}
}
interface PetInterface {
public void talk();
}
class Dog implements PetInterface {
#Override
public void talk() {
System.out.println("Bark!");
}
}
class Cat implements PetInterface {
#Override
public void talk() {
System.out.println("Meow!");
}
public void batheSelf() {
System.out.println("Cat bathing");
}
}
My question is, I cannot access the batheSelf() method because it only exists for Cat. That leads me to believe that I should only declare from an Interface if I am only going to use methods declared in the Interface (and not extra methods from the subclass), otherwise I should declare from the Class directly (in this case Cat). Am I correct in this assumption?
When there is a choice between referring to an object by their interface or a class, the former should be preferred, but only if an appropriate type exists.
Consider StringimplementsCharSequence as an example. You should not just blindly use CharSequence in preferrence to String for all cases, because that would deny you simple operations like trim(), toUpperCase(), etc.
However, a method that takes a String only to care about its sequence of char values should use CharSequence instead, because that is the appropriate type in this case. This is in fact the case with replace(CharSequence target, CharSequence replacement) in the String class.
Another example is java.util.regex.Pattern and its Matcher matcher(CharSequence) method. This lets a Matcher be created from Pattern for not just String, but also for all other CharSequence there are out there.
A great example in the library of where an interface should've been used, but unfortunately wasn't, can also be found in Matcher: its appendReplacement and appendTail methods accept only StringBuffer. This class has largely been replaced by its faster cousin StringBuilder since 1.5.
A StringBuilder is not a StringBuffer, so we can not use the former with the append… methods in Matcher. However, both of them implementsAppendable (also introduced in 1.5). Ideally Matcher's append… method should accept any Appendable, and we would then be able to use StringBuilder, as well as all other Appendable available!
So we can see how when an appropriate type exists referring to objects by their interfaces can be a powerful abstraction, but only if those types exist. If the type does not exist, then you may consider defining one of your own if it makes sense. In this Cat example, you may define interface SelfBathable, for example. Then instead of referring to a Cat, you can accept any SelfBathable object (e.g. a Parakeet)
If it does not make sense to create a new type, then by all means you can refer to it by its class.
See also
Effective Java 2nd Edition, Item 52: Refer to objects by their interfaces
If appropriate interface types exist, then parameters, return values, and fields should all be declared using interface types. If you get into the habit of using interface types, your program will be much more flexible. It is entirely appropriate to refer to an object by a class if no appropriate interface exists.
Related links
Bug ID: 5066679 - java.util.regex.Matcher should make more use of Appendable
Yes, you are correct. You should declare as the most general type providing the methods you use.
This is the concept of polymorphism.
Your are correct, but you can cast from the interface to the desired pet if you need. For example:
PetInterface p = new Cat();
((Cat)p).batheSelf();
Of course if you try to cast your pet to a dog you cannot call the batheSelf() method. It would not even compile. So, to avoid problems, you could have a method like this:
public void bathe(PetInterface p){
if (p instanceof Cat) {
Cat c = (Cat) p;
c.batheSelf();
}
}
When using instanceof, you make sure you will not try to make a dog bathe himself during runtime. Which would throw an error.
Yes, you are correct. By having Cat implent "PetInterface" you can use it in the example above and easily add more kinds of pets. If you really need to be Cat-specific you need to access the Cat class.
You can call method batheSelf from talk in Cat.
Generally, you should prefer interfaces to concrete classes. Along those lines, if you can avoid using the new operator (which always requires a concrete type as in your new ArrayList example), even better.
This all has to do with managing dependencies in your code. It's best to depend only on highly abstract things (like interfaces) because they also tend to be very stable (see http://objectmentor.com/resources/articles/stability.pdf). Because they have no code, they only must be changed when the API changes...in other words, when you want that interface to present a different behavior to the world, i.e., a design change.
Classes, on the other hand, change all the time. Code that depends upon a class doesn't care how it does what it does, as long as the inputs and the outputs of the API don't change, callers shouldn't care.
You should strive to nail down the behavior of your classes according to the Open-Closed Principle (see http://objectmentor.com/resources/articles/ocp.pdf), that way existing interfaces need not change even when you add functionality, you can just specify a new subinterface.
The old way of avoiding the new operator was by using the Abstract Factory pattern, but that comes with its own set of problems. Better is to use a tool like Guice that does dependency injection, and prefer constructor injection. Make sure you understand the Dependency Inversion Principle (see http://objectmentor.com/resources/articles/dip.pdf) before you start using dependency injection. I've seen a lot of people inject inappropriate dependencies and then later complain that the tool isn't helping them...it won't make you a great programmer, you still have to use it appropriately.
Example: you are writing a program that helps students learn physics. In this program, students can put a ball in various physical scenarios and watch how it behaves: shoot it out of a cannon off a cliff, put it underwater, in deep space, etc. Question: you want to include something about the heaviness of the ball in the Ball API...should you include a getMass() method or a getWeight() method?
Weight depends upon the environment the ball happens to be in. It might be convenient for callers to be able to call one method and get the weight of the ball wherever it happens to be, but how do you write this method? Each ball instance must constantly keep track of where it is and what the current gravitational constant is. So you should prefer getMass(), because mass is an intrinsic property of the ball and doesn't depend on its environment.
Wait, what if you just use getWeight(Environment) instead? This way, the ball instance can just get its current g out of the environment and proceed...better yet, you can use Guice to inject the Environment in the Ball's constructor! This is the type of misuse I often see, and people end up blaming Guice for not being able to handle dependency injection as seamlessly as they would've hoped.
The problem is not Guice here, it's the Ball API design. Weight is not an intrinsic property of the ball, so it's not a property that should be accessible from the ball. Instead, Ball should implement the MassiveObject interface with a getMass() method, and Environment should have a method called getWeightOf(MassiveObject). Intrinsic to the Environment is its own gravitational constant, so this is much better. And Environment only depends upon a simple interface now, MassiveObject...but it's job is to contain objects, so this is as it should be.
Why not simply do this!
Cat c = new Cat();
PetInterface p = (PetInterface)c;
p.talk();
c.batheSelf();
Now we have a single object, which can be manipulated using 2 references.
The reference p can be used to call functions defined in interface and c can be used to call functions defined in class(or superclass) only.
I transitioned from Java 1.4(previous company) to Java 1.6 (new company). What I have observed that in case of 1.4 most of the proprietary frameworks were defined using interfaces and template patterns, whereas with 1.6 most of the frameworks are defined around generics.
While I am still trying to get a grip around Generics, my question is - Is this a right design approach? Interfaces make your design more flexible/decoupled. Whereas Generics, implement type safety and enforce you to pass around a specific type of class. Doesn't really help in decoupling your code. Is this correct?
One example -
public MyWizard extends SignupWizard<SignupSection, SignupObject, SignupListener, SignupView>{
}
instead the design would be more flexible if it was ..
public interface Wizardable{
public SignableSection getSection();
public SignableObject getSignableObject();
...
}
public MyWizard implements Wizardable{
....
}
I wouldn't say anything was generics vs interfaces, each have their different needs and uses. Using generic parameters in the way mentioned in the original post serves multiple purposes. It allows developers to define the base classes that make up the field object types of the class. Using this, the developer can accept class objects as parameters which they can use reflection on to create the actual objects and set the fields, or just accept the entire object to set in the first place. The problem which relates to needing class objects rather than doing new T() or such is known as type erasure.
Another benefit of using generics is that you don't need to typecast all the time when using fields or methods from a superclass -- you personally know their types, but Java doesn't have that type information stored anywhere. An additional benefit is that all your getter / setter methods can use the generic parameters and expose a more sensible front to other objects which rely on the fact that you set up specialised fields in the aforementioned object.
The problem with using interfaces to do the same thing that generics does is that you need additional methods to access the specialised types and cast them, before returning them (or check incoming types and then set fields to the objects). It's making the design more complex, and doesn't really help with decoupling at all.
As I mentioned in a comment, any subclasses will set those type parameters and expose nothing to the user. So you can have something like class MegaSignupWizard extends SignupWizard<MegaSignupSection, MegaSignupObject, MegaSignupListener, MegaSignupView> and everything remains perfectly valid with MegaSignupWizard having access to specialised methods in the classes without any need to cast. Now that's cool :)
Generics allows you to implement methods on the general type while interfaces only define the signatures. Maybe it's abused sometimes to act like Scala's trait, but mostly they serve two different purposes. If everything was an interface, there is going to be a lot of duplicated code or delegations to some helper class.
I've noticed that many of the new frameworks tend to use annotations instead of interfaces, but I haven't noticed them using generics instead of interfaces (whatever it means - please explain more).
With the help of generics, its possible to reduce some code duplication and to improve type safety, when you have one interface with generic type parameters and the same interface will work for lots of different types. The collections in the java.util package are a good example of when generics are useful.
In the case of annotations, sometimes I feel they are overused and an interface would be better - for example with an interface it's easy to know what parameters a method should take - but on other cases an annotation is more flexible and powerful.
I think it's generics and interfaces, since any interface can make use of generics itself. The problem I see when you start to use generic (abstract) classes you lose the flexibility of using composition. While there is nothing bad about inheritance as such you have to design for it and there are many pitfalls.
Take a look at Jung2 to see where Generics become really powerful. Basically, any object can be a vertex or an edge which makes for some really interesting ideas in network algorithms. You couldn't do this with just interfaces.
I'm not sure your above use looks good either. If you're extending from an object or implementing an interface you don't really want to be passing objects like that. Generics are used to implement a class with abstract type, like a collection, that could act on anything. What happens if I pass SignupWizard<int, int, int, int> which is perfectly valid?
For that particular idea, perhaps you do want to use interfaces. Have an interface defining wizardaction, each object implementing it and mywizard being able to .addaction(int position, wizardaction action). In fact that is definitely an interfaces problem.
I'd agree with the others - generics have been used when they're needed by libraries.