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.
Related
This question already has answers here:
Test if object implements interface
(7 answers)
Closed 3 years ago.
I am trying to create a function which takes two parameters - a class instance and a interface - then returns true if the provided class instance implements the provided interface. My problem is that I cannot find a way to pass a interface as a parameter in this way.
My attempt currently looks something like this:
interface myInterface
{
}
class myClass implements myInterface
{
}
...
// Function to check if a class implements an interface:
boolean doesImplementInterface(object classToTest, ??? interfaceToTestAgainst)
{
if(i.getClass().isInterface())
{
return o.getClass().isInstance(i);
}
return false;
}
...
// Would call the "doesImplementInterface" method like this:
doesImplementInterface(new myClass(), myInterface);
It might be hard to see here, but when defining the "doesImplementInterface" function, I cannot figure out what type the second parameter must be. I am attempting to pass the interface that the provided class will be tested against, but as far as I can find, there is no variable type that I could use to pass a interface in this way.
Is passing a interface as a parameter in this way possible, or should I begin exploring alternative options?
Explanation
You need to pass the interface as Class (documentation) token. Also, you need to check the opposite way: interfaceToTestAgainst.isInstance(classToTest). Currently, you are trying to check whether the interface would be an instance of the class.
boolean doesImplementInterface(Object classToTest, Class<?> interfaceToTestAgainst) {
if (!interfaceToTestAgainst.isInterface()) {
return false;
}
return interfaceToTestAgainst.isInstance(classToTest);
}
or in one line:
boolean doesImplementInterface(Object classToTest, Class<?> interfaceToTestAgainst) {
return interfaceToTestAgainst.isInterface()
&& interfaceToTestAgainst.isInstance(classToTest);
}
Changed the naming a bit:
boolean isInstanceOfInterface(Object obj, Class<?> interfaceToken) {
return interfaceToken.isInterface()
&& interfaceToken.isInstance(obj);
}
A call of that method:
boolean result = isInstanceOfInterface(new Dog(), CanBark.class);
Note
Your question sounds like a XY problem. There might be way better solutions to solve what you are trying to solve with this attempt in the first place.
Losing type information, degrading the system to one which is not compile-time-safe anymore is generally very bad, if it can be avoided.
Consider re-thinking/-designing your approach. Just a note though, I do not know what you want to solve with that in the first place.
You do not need to create a method for this. Simple use
boolean doesImplement = ITest.class.isAssignableFrom(Test.class)
in case of instance, use instance.getClass() i.e.
boolean doesImplement = ITest.class.isAssignableForm(testObj.getClass())
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
}
I'd like to write a method that checks where the argument is null, and if it is, returns a new object of that type. it looks like:
public static <T> T checkNull(T obj) {
if (null == obj) return someHowCreateTheObjectWithTypeT();
else return obj;
}
After some struggling and digging, I still can't get a way to achieve this, is it atually possible in java?
I thought about reflection at first. But I just can't get a Class instance when the object is null, and you can't create a Class without the type T's name...
Update:
I thought about passing a Class as a parameter, but that's not the best solution, as the following answers shows :)
My currunt solution is to use a defaultValue parameter:
public static <T> T checkNull(T obj, T defaultValue) {
if (null == obj) return defaultValue;
return obj;
}
Which is faster and safer than a reflection solution, and is the same verbose;
But then I have to systematically specify a DEFAULT_VALUE for all types of interest, which is not an easy work.
This is not possible. For generics to work in this manner, it has to capture at compile-time the type that it will be called with. However, null has no type so you won't be able to figure out T to instantiate it.
Now, you may be able to work around this also passing in the Class instance, but you will need some rather robust error handling using Reflection to ensure that type T is a concrete class and has a public parameterless constructor that you can invoke.
Generic information is compile time only and not available at runtime. You'd have to pass the Class of the object in as a hint, and the class would have to have a public default constructor. e.g.
public static T checkNull(Object o, Class<T> c) {
try {
return (o == null) ? c.newInstance() : o;
} catch (Exception e) {
return null;
}
}
Cannot be done. You must add an additional parameter of Class<T>, and then use it to reflectively new. The type T does not survive the compilation process.
As others have pointed out, this can't be done. However, Guava provides an equivalent to the default value you method you posted:
String foo = Objects.firstNonNull(someString, "default");
This differs slightly from your method in that firstNonNull will throw a NullPointerException if both arguments are null.
Another option would be to create a method that makes use of Guava's Supplier<T> interface or something similar:
public static T firstNonNull(T first, Supplier<? extends T> defaultSupplier) {
return first != null ? first : Preconditions.checkNotNull(defaultSupplier.get());
}
You could then use a Supplier that creates and returns a new default instance when and only when the first argument is null.
I have a method that usually takes an item from a list and has a signature of:
myMethod(T item)
I want to use this method but I know what I am sending the method.
SpecificItem myItem = new SpecificItem();
myMethod((T) myItem);
This doesn't sit well with me. Is this a sign of bad code?
myMethod is defined in a generic class, somewhat like:
public class MyClass<T> {
T myItem;
public void myMethod(T item) {
// do Something with item
}
public T myOtherMethod() {
myMethod(myItem); // casting is not necessary
return myItem;
}
}
If you instantiate this class, you exchange the variable type T with a real one:
MyClass<SpecificItem > concreteClass = new MyClass<SpecificItem >();
And if you call myMethod on this instance, you have to provide a SpecificItem, because SpecificItem is the generic type for this instance.
(I'm not sure it my post answers your question, please comment so I can improve it)
It's better that you code to interface. For example :
In myMethod :
<T extends <? super Item>> void (T item);
This tells compiler to only accepts a generic type of T which is an implementation/extention of Item interface/class. This will make sure that given input is in correct type. Compiler guarantees it.
In main class :
Item myItem = new SpecificItem();
Code given above is the best practice. Get used to it. But (i discourage this) you can code like this too :
SpecificItem myItem = new SpecificItem();
You can read Java source code. For example in class java.util.Collections. In method sort(List) you may notice that Joshua Bloch makes sure that given input is always in correct format. To give it a try, do this :
public class Class1 {
public static void main(String[] args) {
List<Class1> list = new ArrayList<Class1>();
Collections.sort(list);
}
}
Above code will produce compilation error. To fix this compilation error Class1 must implement interface Comparable. This maintains the precondition of method sort(List) which assumes that given input is a List of Comparable.
Oh i almost forget about your question. Actually it's not a bad code since it works. I just want to tell you that there is a better way to do that.
You might be looking for something like this:
class C<? extends T> {
public void myMethod(T myItem) {
...
}
}
The way you call the method looks strange. If you have declared your generic method as
public <T> void myMethod(T item);
the compiler knows, that T is some abstract type and you shouldn't need to cast an input parameter to it. Just make sure, that T is not declared as some specific type in your code.
upd: look here for an example: http://www.java2s.com/Tutorial/Java/0200__Generics/Usinggenericmethodstoprintarrayofdifferenttypes.htm
Probably better way would be to make SpecificItem a subclass of T or make T an interface and have SpecificItem implement it.
I stumbled upon a function looking like this:
public void function(Class<?> clazz) {...}
What are the pros/cons of changing the method to:
public <T> void function(Class<T> clazz) {...}
edit: what are the compile time / runtime diff.
todd.run is totally right on, but that's only half the answer. There are also use cases for choosing <T> over <?> (or vice versa) that apply when you don't add type parameter to the class that encloses the method. For example, consider the difference between
public <E extends JLabel> boolean add(List<E> j) {
boolean t = true;
for (JLabel b : j) {
if (b instanceof JLabel) {
t = t && labels.add(b);
}
}
return t;
}
and
public boolean add(List<? extends JLabel> j) {
boolean t = true;
for (JLabel b : j) {
if (b instanceof JLabel) {
t = t && labels.add(b);
}
}
return t;
}
The first method will actually not compile UNLESS you add an appropriate type parameter to the enclosing class, whereas the second method WILL compile regardless of whether the enclosing class has a type parameter. If you do not use <?>, then you are locally responsible for telling the compiler how to acquire the type that will be filled in by the letter used in its place. You frequently encounter this problem - needing to use ? rather than T - when attempting to write generic methods that use or need "extends" and "super." A better but more elaborate treatment of this issue is on page 18 of Gilad Bracha's Generics Tutorial (PDF). Also see this stack overflow question whose answer illuminates these issues.
Check out this stack overflow link for information about your second question: Java generics - type erasure - when and what happens. While I don't know the answer to your question about the compile time difference between <?> and <T>, I'm pretty sure the answer can be found at this FAQ that erickson mentioned in that post.
Using "?" is the same as "any", whereas "T" means "a specific type". So, compare these interfaces:
public interface StrictClass<T> {
public T doFunction(Class<T> class);
}
public interface EasyClass<T> {
public > doFunction(Class<?> class);
}
Now, we can create classes:
public class MyStrictClass implements StrictClass<String> {
public String doFunction(Class<String> stringClass) {
//do something here that returns String
}
}
public class MyEasyClass implements EasyClass<String> {
public String doFunction(Class<?> anyClass) {
//do something here that returns String
}
}
Hope that helps!
Basically, they are equivalent. You can use the first syntax where you don't need to declare anything of type T.
UPDATE: oh, and T can be used to bind types together: if Class<T> is used in different parts of the function it will refer to the same class, but not Class<?>.
A good resource might be this: http://sites.google.com/site/io/effective-java-reloaded
The interesting part related to your question starts around the 5th minute.
Just in addiction to what previous users said.
Hope that helps :]