I have a little question about generic-programming in Java. Is there any way to check the type of the parameter passed to the method? I would like to compare the types of an instance which calls the method, and the parameter passed to it.
If they are not the same, the action of the method should be stopped (kind of protection).
public void homeMatch(SportTeam<Type> visitors){
if(the type of visitors and this-object are not the same){
//do this
}
else{
//do something different
}
}
You cannot operate with Type at runtime as it is erased by the compiler. It only exists at the source code for design purposes.
Being more specific, this method signature will be compiled to something like
public void homeMatch(SportTeam visitors)
What you could do, if you really want to have that check, is to add a class parameter to the functions arguments. Than compare the classParameter with the class of this. This would work because visitors have the same generic type as typeClass.
public<Type> void homeMatch(Class<Type> typeClass, SportTeam<Type> visitors){
if (typeClass.getClass() == this.getClass()){
}
}
if I understand correctly you must use instanceof .
like this:
if (visitors instanceof Type) {
// action
}
Related
I'm working with java and have some question about methods, there is no code to correct, only a question for why is good to return into method a class?
public class Bird { public Bird bird() {return null;} }
Can you explain when and why i should return class from method? And how this gonna work?
It's not a must to return class, compiler expects value in return but it does not has to be a class. It depends what you are planning to do with a method, you could return any data type be it int, String, character, Arrays, Object etc or say when you don't want to return anything that's void return type.
if you were to look at method definition,
//do whatever
return returnType;
}
it clearly has returnType in method definition, which tells compiler what to expect back from method as a return value.
In your example, i do not know the context but the way you posted your method it says Bird as returnType, which means either compiler is expecting you to return BirdType object or you could also return null.
P.S. i didn't have the said reputation to add it to comments :/
I'm sorry if this is already asked but here is my question. I would like to create a function where the parameter that the user inputs can be any variable type, similar to System.out.println().
That being said how would I create that method?
public static void example(String, int, double, etc.) {
//Code here
}
You need to change all the method parameters types to Object.
public void myMethod(Object o){
// ...
}
Please note that in order to access o as a certain type of other class you will need to first test if it is in fact that class with if(o instanceof OtherClass) and then cast it with OtherClass o2=(OtherClass) o. Casting is expensive (hogs a lot of CPU (for a simple operation)) though so avoid if possible. If you just need a string representation of o then just call o.toString().
public class Test<T>{
public boolean isMember(T item) {
if(item instanceof Test)
{
return true;
}
return false;
}
}
Is this the correct way to check if the item is an instance of the class?
I went through some searches and it seems that for a generic class, this will not work.
It's unclear what you're trying to test here, but here are a few possibilities:
Is item a T? Yes. Otherwise, it presumably couldn't be passed into the isMember method. The compiler would disallow it. (See Alex's caveat in the comments below.)
Is item a Test? Your isMember method as it is written would test this, but I'm sensing a code smell here. Why would you expect a T to also be a Test, but only some of the time? You may want to reconsider how you're organizing your classes. Also, if this is really what you want, then your method could be written as:
public boolean isMember(T item) {
return (item instanceof Test);
}
Which begs the question: why have a method like this in the first place? Which is easier to write?
if(obj instanceof Test) {...}
or
if(Test<Something>.isMember(obj)) {...}
I would argue that the first one is simpler, and most Java developers will understand what it means more readily than a custom method.
Is item a Test<T>? There is no way to know this at run time because Java implements generics using erasure. If this is what you want, you'll have to modify the method signature to be like Mike Myers's example.
T is not a variable, but a place holder for a class that is defined at runtime. Generics are a compile time feature, for that reason they add checks at compile time which may not have any meaning at runtime. We can only check the type of the object referenced at runtime which could be a super class type in the code. If we want to pass the type T as parameter to the method, all we have to do is to approach explicitly like the following:
void genericMethod(Class<T> tClass) {
if(String.class.isAssignableFrom(tClass))
or
void genericMethod(Class<T> tClass, T tArg) {
Note that the type might not be the same as here we can see how to manipulate:
genericMethod(Number.class, 1);
public class LinkList<T>{
public boolean isMemberOfClass(T item) {
if(item instanceof LinkList)
{
return true;
}
return false;
}
}
I'm sorry, I'm not suppost to post question as answer.
the class LinkList is a generic class.
the function is to check if the item belongs to the class. check if the have the same T.
Guys I know this question is silly but just to make sure:
Having in my class method:
boolean equals(Document d)
{
//do something
}
I'm overloading this method nor overriding right? I know that this or similiar question will be on upcoming egzam and would be stupid to not get points for such a simple mistake;
Based on the code provided, we can't tell for sure whether you're overloading or overriding it.
You are most likely overloading the equals(Object o) method.
class A {
void method() {..}
}
class B extends A {
// this is overriding
void method() {..}
}
And
// this is overloading
class A {
void method(boolean b) {..}
void method(String arg) {..}
void method(int arg) {..}
}
P.S. you are using a bracket convention that is not widely accepted on the java world. In Java it is more common to place opening the curly bracket on the same.
You are not even overloading, since the other method is called equals. But if you add that s, you will be overloading equals. Although, to be precise, we talk about overloading if two (or more) methods with the same name but different signature are defined in the same class. In your case, it is trickier, since your equals with its different signature partly hides the original equals. Which is usually a bad thing, because this almost always leads to hard to understand behaviour, thus subtle bugs. Whenever someone calls equals on an instance of your class, depending on the parameter type the call may go to a different implementation of the method.
class Document {
public boolean equals(Document d)
{
//do something
}
}
Document doc1 = new Document();
Document doc2 = new Document();
String string = new String();
doc1.equals(doc2); // calls Document.equals
doc1.equals(string); // calls Object.equals!
You would be overriding Object.equals if you defined your method with the exact same signature as the original, i.e.
public boolean equals(Object obj) ...
In this case, both of the above calls to equals correctly execute Document.equals.
From the code you posted it could be either. If equal is defined in a superclass with the same parameter declarations then you are overriding it. If there is already a method called equal, but with different parameter types, you are overloading it.
On a related note, if you are using Java 5 and above and your intent is to override then it is highly recommended to use the #Override annotation before the method definition to indicate your intention. The wrong usage of this annotation (i.e. when you want to override and are not doing so) would flag a compile error.
As of Java 6 you can use the #Override annotation while defining methods that are
declared in an interface the class in implementing.
Overloading: same method name, same parameter list, different classes
Overriding: same method name, different parameter list, same or different classes.
Class A {
bool Equals(Document d) {...}
bool Equals(A a) {...} // overloaded method
}
Class B extends A {
bool Equals(Document d) {...} // overridden method
bool Equals(B b) {...} // overloaded method
}
One thing to note, the return type does not matter, it's the name of the method and the parameter list that make all the difference.
I have a class tree like this:
master class abstract class Cell
AvCell extends Cell
FCell extends Cell
i have an abstract method getValue() in Cell
Is it posibble to make the method getValue() to return int for AvCell and String for FCell?
Can i use generics for int String?
Thanks!
You could use generics and declare a Cell<T>.
Then just have getValue() return T
abstract class Cell<T> {
abstract T getValue();
}
Now:
class AvCell extends Cell<Integer> {
}
and
class FCell extends Cell<String> {
}
No. You can, however, narrow the return type when subclassing. This is known as "covariant return types". If a method in a base class returns T, you are allow to override that method in a subclass and have it return a subclass of T.
You can do the following:
abstract class Cell<T> {
public abstract T getValue();
}
class AvCell extends Cell<Integer> {
public Integer getValue() {
return 0;
}
}
class FCell extends Cell<String> {
public String getValue() {
return "foo";
}
}
Nope, no overloading on return types.
You could declare the return type to be Object and return either an Integer or a String, if you really want to.
You cannot do that normally. You have to have return types declared and the value being returned should be of the declared type or a subtype.
There are other ways to do that - declaring the method return type as Object and returning anything you want, but this is NOT the way to go.
First, a very simple question: Why do you want to return different types based on different input conditions? Generally this should be because you are doing two different things in the method based on the type you are passing. This is the place to look at. Have different methods for the different types and call one of them based on the type at hand. (And you can go further using factory patterns...)
If I understand the (changing) question correctly : No
From the Sun Java Tutorial:
Overloaded methods are differentiated by the number and the type of the arguments passed into the method. In the code sample, draw(String s) and draw(int i) are distinct and unique methods because they require different argument types.
You cannot declare more than one method with the same name and the same number and type of arguments, because the compiler cannot tell them apart. "
You can't overload the return type of a method. The JVM would not know which method to use, because the signatures are the same.
But, you could return Object, with one filling out Integer and the other String.
Yes, JVM actually allows it, so it can be done if you can generate byte codes correctly. The catch is you have to use a different tool other than javac. Here is a good tutorial: http://today.java.net/pub/a/today/2008/07/31/return-type-based-method-overloading.html
Why is it important? We built a library but want to change the return type from void to something else. Unfortunately, it required all applications depending on it to recompile. By manipulating bytes codes, the old applications can run without recompiling.