I had a job interview today and I was asked, if the code below is a good example/case of using reflection in C#:
public abstract class Level{
public string LevelID { get; private set;}
public int LevelNumber {
get{
return int.Parse(LevelID.Substring(5).ToString());
}
}
public Level(){
this.LevelID = GetType().ToString();
}
}
I assume the use of the code above would be:
class Level32 : Level{
// call base class constructor...
}
and then
Level32 level = new Level32();
int id = level.LevelNumber; // would print 32.
I think the guy meant this line: this.LevelID = GetType().ToString();
I said that there's no reflection at all.
As good as I know Java, calling SomeClass.class.getName() does not use any of the 'reflective' packages, so it doesn't use reflection at all. I thought that C# is built that way too.
Am I dumb, or he is?
I think that, strictly speaking, the GetType() call is reflection, yes.
See https://stackoverflow.com/a/24377353/8261
However, it is only the most trivial reflection, so I wouldn't think you were "a "Hello World" kid" for discounting it. :-)
Am I dumb, or he is?
I don't like this framing: it seems to me that neither of you are (or perhaps both of you are, for getting into an argument over trivial semantics).
First sentences from Microsoft docs:
Reflection provides objects (of type Type) that describe assemblies, modules and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object
Method GetType() returns object of type Type and is used (obviously) to "get the type from an existing object". Looking only at those rules we can say it is reflection.
To be clear, I consider this a bad question for interview, there a better ways to check if candidate understands reflection.
I don't have 50 reputations to add comments. Please don't mind me adding it as an answer. :)
We already have a few good answers about GetType().
I'd like to answer "is a good example/case of using reflection?".
I think the intended answer is "No".
The keywords here are abstract and GetType(). The point of creating abstract classes and interfaces is that the caller doesn't have to know what the exact type it is.
If we still have to know the actual type of the sub-classes, we're not using it correctly.
So I think this is not really a question about reflection. It's more like a question about OOP/inheritance.
That's just my 2 cents.
Related
apologies if this is simple or has been answered before, I'm new to Java and in my research I can't find too much on this issue and have not yet found a solution.
I have an ArrayList with multiple classes that all share a common Interface, in this example the interface is called "Packable". I'm trying to create a method that takes a class parameter and sweeps through each element of this ArrayList, returning a new list containing all the items in the original list that are of the same class as the reference parameter.
This is my code so far, trying the instanceof method:
public List<Packable> getOfType(Packable reference){
List<Packable> typeOfItems = new ArrayList<>();
for (Packable item: itemsStored) {
if (item instanceof reference){
typeOfItems.add(item);
}
}
return typeOfItems;
}
This is throwing an error as it doesn't yet recognise reference as a class. This question mentions a method isAssignableFrom with the answer stating: "When using instanceof, you need to know the class of B at compile time. When using isAssignableFrom() it can be dynamic and change during runtime." (Thanks Marc Novakowski)
I understand that given the parameter the class isn't known at compilation and as such I've tried implementing isAssignableFrom and can't really seem to get it to work. The IDE doesn't really recognise or suggest it, and there isn't too much about the method online. I've tried implementing it the way the JavaDocs suggest but this isn't working either:
if (reference.isAssignableFrom(item.getClass())){
typeOfItems.add(item);
}
Any help or advice on methods to look into would be greatly appreciated. Thanks for reading the question, and again apologies if this is simple or has been answered elsewhere and I've just missed it. Thanks everyone
I'm not sure what Packable is, but you appear to be confused about a few concepts here.
In java, Packable reference does not represent the Packable concept. It represents a specific instance of Packable (or null).
In other words, given Dog dog, that means dog is some specific dog. Not 'the general concept of a dog'. We know that the specific animal that dog is referring to is, at least, a Dog. It could be Fifi, the neighbour's schnauzer.
instanceof, on the other hand, is about the general concept of things: if (fifi instanceof Dog) is how you're supposed to use it. You're more or less attempting to do the equivalent of if (fifi instanceof rover) which just doesn't make sense. How can one dog be 'an instance' of another? It's not that the answer is 'true' or 'false', but that the very question doesn't even make sense, which is why javac doesn't compile it. It has no idea what this even means.
Java, being java, makes objects of many things. Notably including the very notion of things. Thus, there is the class java.lang.Class, instances of which represent classes. A bit of alice-going-down-the-rabbit-hole thing is happening here: Classes as a concept are also represented as instances of the java.lang.Class class.
A class OBJECT (so, an instance of java.lang.Class) has the .isAssignableFrom method. This in fact takes another j.l.CLass as argument, it's for checking if one type is a subtype of another. In that sense, the question linked is needlessly confusing - you're really looking for the instanceOf method (there is an instanceof language construct, but the j.l.Class class has an isInstance method, which is unrelated, other than that they roughly accomplish the same goal: Check if some INSTANCE is of a type that is equal to, or a subtype of, some TYPE.
This is an example of how to use it:
Class<?> c = Number.class;
Object o = Integer.valueOf(5);
System.out.println(c.isInstance(o));
this is more or less equivalent to:
Object o = Integer.valueOf(5);
System.out.println(o instanceof Number);
Except now the Number part no longer needs to be written at 'write the code' time, you can supply it, say, read it from a parameter. You'd have to, of course, dynamically construct the Class instance. You can do so either by string-lookup, or by getting the actual type of an actual object. For example:
String input = scanner.next(); // user types in "java.lang.Number"
Class<?> c = Class.forName(input);
Object o = Integer.valueOf(5);
System.out.println(c.isInstance(o));
Or:
Object i = Integer.valueOf(5);
Object d = Double.valueOf(10);
Class<?> c = i.getClass(); // will be java.lang.Integer.class
System.out.println(c.isInstance(d)); // false
But doing this latter bit is really dangerous. Often i.getClass() returns some hidden impl detail subtype (java is hierarchical and object oriented, anywhere, say, an ArrayList is needed, someone is free to make a new class: class MyVariantOfArrayList extends ArrayList, and use that - now you write ArrayList foo = getList(), but foo.getClass() doesn't return ArrayList - no, you invoke that method on the object the foo variable points at, so, it'd be MyVariantOfArrayList.class, not ArrayList.class.
It's possible Packable itself represents a type. But then it either needs to also have isInstance and isAssignableFrom and such (and you need to start questioning why you're badly reinventing the wheel here - java.lang.Class already exists!), or it needs a .getRepresentedClass() method. You can't call it .getClass(), as the JVM has already given all objects that method, and it would return Packable.class itself.
Now I've been studying Java for some time now but there's a concept I'm struggling to wrap my head around. I'm used to methods like these
public int something () {
}
I know the above method will return an Integer or a String whatever data type you want. I've recently encountered a method like these
public customclassname methodname(){
}
now I was asking myself what on earth is the return type of the above method. How do I use the returned thing to do something else?
I also saw people passing objects to methods as parameters like this
public something methodname(Customclass customclass){
}
What's the deal with that too? In what scenario is the above "style" necessitated and what are the pitfalls to avoid?
Using objects instead of values like integers or whatnot is confusing me.
I know the above method will return an Integer or a String whatever data type you want.
Yes, that's correct. Now add to that the fact that classes are data types and this should become more clear. A Customclass that you define is still a data type that can be the return type of a method, or the type of a value passed in as a method parameter.
For "pitfalls to avoid" you should probably read up on Is Java "pass-by-reference" or "pass-by-value"?
This morning I woke up on this strange exception:
java.lang.ClassCastException:
org.apache.harmony.luni.lang.reflect.ImplForVariable cannot be cast to
java.lang.Class
It happens when I try to get a Type argument Class.
Example:
public static Class getTypeParameterClass(Object o, int index) {
return (Class)
((ParameterizedType)o.getClass()
.getGenericSuperclass())
.getActualTypeArguments()[index];
}
As you can see, this method gets one of the type parameter for a given object's class.
It's been working for months now but today, it stopped.
Usage example:
Collection<Object> foo = new ArrayList<Object>();
Class<?> fooClass = Utils.getTypeParameterClass(foo, 0);
And it crashes.
Is there a curse on me for blaming java too many times;) ?
Thanks !
As you can see, this method gets one of the type parameter for a given object's class.
So what you are doing is specifically not allowed because of the generic type erasure. You are trying to investigate the generic parameter of your ArrayList but when the code is running, the specific generic type is no longer visible.
Your superclass hack (and it is a hack) would work if you were dealing with a superclass. It would work if you defined your ArrayList like:
Collection<Object> foo = new ArrayList<Object>() {
private static final long serialVersionUID = -594043150300376049L;
};
In this case foo is a class which extends ArraryList. For some reason with the superclass the generic type parameter is available.
So, first of all, let me address a huge "thank you" to Gray for his patience.
I finally figured what was wrong.
I was focusing on the wrong field.
So, as Gray points out, because of type erasure you can't get a type parameter that is not explicitly given at compile time.
I was so persuaded that the error was on a Collection field that I totally forgot about other fields.
So, because my data come from webservices, and because the JSON mapper can't directly get a list as root, I had to define models containing a Collection of objects, a date (for caching) and few other things related to paging.
So, because writing all these similar classes was a nonsense, I tried to generalize the process, like so:
public abstract class ModelList<T> {
[ paging and caching stuffs ]
#ForeignCollectionField
Collection<T> collection;
[ constructor, getters, setters ]
}
and then only have subclasses like:
#DatabaseTable(tableName = "category_list")
public class CategoryList extends ModelList<Category> {
}
So I could have less verbose classes, and so I could generalize the caching process using ObjectPersister from Robospice.
What I couldn't understand (because of a lack of knowledge), is that the parameter would not be found at run time !
What confused me even more is that the tests I ran to try to reproduce the bug, WERE producing the bug ! but they were wrong too.
So, note to self (and others that may face complete nonsense like I did):
don't lose faith in the language (it's not buggy, it's not buggy, it's not buggy ...)
don't blame the language (not too much)
always attach sources to jars and set breakpoints
At the end the solution was quite simple, just move the collection from the ModelList to the sublasses, and keep the getters and setters as abstract methods in ModelList (for the generic ObjectPersisters).
I think it all got a little too complicated, if someone knows a better solution for this case using ormlite/jackson/robospice I'd be glad to hear it.
This question already has answers here:
Methods With Same Name as Constructor - Why?
(7 answers)
Closed 9 years ago.
Java allows to create method which has the name of the class and type void ( Like void constructor). Constructor has no type and it do the function of the constructor. But is there any usage above mentioned kind of methods. Can you give examples of those usages
Sample Code:
//my class
class MyClass{
//constructor
public MyClass(.....){
}
//What is the use of the below method
public void MyClass(....){
}
}
To answer your question: No, it has no special use. In fact, it is counter intuitive and confusing. Some compilers will even generate a warning "This method has a constructor name".
But because technically it is possible that it is not a compilation error, I would advice staying away from it. There are several different method names which can be more descriptive and serve the same purpose.
Yes, A fresher to Java may confuse with this. The constructor cannot have a return type. But some people misunderstand that the "no return type" and "void" are some what equal but it is not. Constructor is a different story and the method that has the class name and any other return type (void, String, int, .......) is different. But it is more confusing.
There is no sensible usage for a method those name is the same as the class name.
It is a style violation. According to the official Java style guide, names of Java methods should start with a lower case letter.
It is confusing because it looks superficially like a constructor.
It is confusing because when you use such a method it looks like you are using the classname incorrectly.
It is possible that this will result in unexpected behaviour and/or unexpected compilation errors due to the class-name vs method-name ambiguity.
Why java allows method that has class name and type void?
Basically because the Java language does not enforce the identifier style rules. (IMO, it would have been better if it did enforce the rules ... but the decision was made a long time ago, and it can't be changed for compatibility reasons.)
No It don't have special usage, it will be treated as similar to other methods inside the class.
It will be worth reading below article:
http://docs.oracle.com/javase/tutorial/java/javaOO/methods.html
If the method name is same as class name and it has no return type then its known as constructor which has special usage in oops.
by keeping such names as method it will only create a confusion and code readabilty.
below link will might help you why readibility matters:
http://java.dzone.com/articles/why-code-readability-matters
The usage is identical to that of any other method. And the return type need not be void. It can often be confusing, but it is perfectly legal to name methods the same as the class name. It'll usually cause more confusion then you want, but it's a legal behavior. The methods have no special properties apart from any other class method.
I know well, what is a class literal in java, I just wonder, what is the reason for the .class in the syntax. Is there any ambiguity removed by this? I mean, wouldn't an alternative Java syntax using
Class<String> c = String;
instead of
Class<String> c = String.class;
work? To me the class keyword looks like a boilerplate.
Sure, you could make that the syntax. But using the .class suffix makes the compiler's job easier; it has to do less work to know that the code is syntactically correct.
Without the suffix, the compiler would have to work harder to understand the difference between this:
String.getName() // a method inherited from java.lang.Class<T>
and this:
String.valueOf(...) // a static method from java.lang.String
If you don't think that the .class suffix is needed, do you also think that the f and L suffices are useless (for float and long literals, respectively)?
It's just not the same thing. String is a class of type string, and String.member is one of its member variables, String.method() would be one of its methods.
String.class is an object of type Class that defines String. It seems a lot more intuitive that you need to specify .class to indicate that you're trying to refer to an object of type Class.
Not to mention that it's easier to parse this kind of construct, and potentially prevents bugs where you're accidentally returning a Class object when you didn't mean to.
This is even more relevant when you're looking at inner classes, like OuterClass.InnerClass.class.
To work with Matt's example: How would you work on the class object without having to create a temporary variable first? Assuming your class Foo has a static method called getClasses, how would you differentiate between Foo.getClasses and Foo.class.getClasses?
String is the String class pseudo-object which provides access to the classes static fields and methods, including class, which refers to the Class instance which describes the String class. So they are distinct, but because Java doesn't have the metaclass arrangement of (say) Smalltalk-80 this isn't very clear.
You could certainly make String and String.class synonymous if you wanted to, but I think there is a valid basis for the distinction.
Let's use integer as an example:
Class<Integer> c = Integer; // your proposal
int i = Integer.MAX_VALUE; // compare with below
int j = c.MAX_VALUE; // hmm, not a big fan, personally
It just doesn't seem to flow, in my opinion. But that's just my opinion :)