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 :)
Related
Let's say I want to write isSubdirectory static function in my FileUtils helper class. This function would look like:
class FileUtils {
public static boolean isSubdirectory(File child, File parent) {
// ...
}
}
Or I could flip parent and child parameters:
class FileUtils {
public static boolean isSubdirectory(File parent, File child) {
// ...
}
}
And I cannot choose which order is right...
In Kotlin there would not be any doubts: just declare extension function:
fun File.isSubdirectory(parent: File) {
// ...
}
With an eye on kotlin I have invented mnemonic rule: first parameter in static function should be considered as this (I'm not the first who invented this rule. I saw many people also using it). So in this example I'd prefer placing child as first parameter.
But the question is: is this rule is already formalized and has well known name? I've tired to repeat this rule to people who don't know it and I wish I could simply refer to this rule by it's name.
I'm not sure that there's a name or any real formalization. At best, it's just a common convention to have the first parameter look like the this.
Although rarest, the "this last" convention also exists, more in C and early C++ (Example: stdio with fread/fwrite)
There also exist conventions based on the argument type; for example promoting the following order:
Collection and other objects with generic parameters
Arrays of objects
Objects without generics
String
Arrays of primitive types, e.g. byte[]
double, float
long, int, short, byte
boolean
There also exist the more or less exact opposite order. Other conventions also tend to group arguments by their type, prefering method(String, String, int, int) rather than method(String, int, String, int).
As you can see, there are a lot of conventions that exist. I'm not sure that any of them has a name, and that any is really much more used than any other.
It isn't as clear as camelCase vs. snake_case for example, which almost no one contradict.
What you can keep from all that is the following: put the arguments in the order that looks the most logical and straightforward to you.
The most important is to stay consist in the entire project, i.e. don't write isFileX(a,b) and then isFileY(b,a) for example, a fortiori if the two methods are in the same class.
IN case of doubt, don't hesitate to ask other people working on your project what they think is the best.
For your particular case, it's reasonnable to put child first because of the "this first" rule, but it's as reasonnable to put the parent first, as it's also a common convention for example in GUI frameworks.
It's up to you to decide.
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.
I'm learning Scala at the moment and I came across this statement in Odersky's Programming Scala 2nd edition:
one way in which Scala is more object-orientated than Java is that classes in Scala cannot have static members.
I'm not sufficiently experienced in either Java or Scala to understand that comparison. Why does having static members make a language less OO?
Odersky's statement is valid and significant, but some people don't understand what he meant.
Let's say that in Java you have a class Foo with method f:
class Foo {
int f() { /* does something great */ }
}
You can write a method that takes a Foo and invokes f on it:
void g(Foo foo) { foo.f(); }
Perhaps there is a class SubFoo that extends Foo; g works on that too. There can be a whole set of classes, related by inheritance or by an interface, which share the fact that they can be used with g.
Now let's make that f method static:
class Foo {
static int f() { /* does something great */ }
}
Can we use this new Foo with g, perhaps like so?
g(Foo); // No, this is nonsense.
Darn. OK, let's change the signature of g so that we can pass Foo to it and have it invoke f.
Ooops -- we can't. We can't pass around a reference to Foo because Foo is not an instance of some class. Some people commenting here are confused by the fact that there is a Class object corresponding to Foo, but as Sotirios tried to explain, that Class object does not have an f method and Foo is not an instance of that class. Foo is not an instance of anything; it is not an object at all. The Class object for Foo is an instance of class Class that has information about Foo (think of it as Foo's internal Wikipedia page), and is completely irrelevant to the discussion. The Wikipedia page for "tiger" is not a tiger.
In Java, "primitives" like 3 and 'x' are not objects. They are objects in Scala. For performance your program will use JVM primitives for 3 and 'x' wherever possible during execution, but at the level you code in they really are objects. The fact that they are not objects in Java has rather unfortunate consequences for anyone trying to write code that handles all data types -- you have to have special logic and additional methods to cover primitives. If you've ever seen or written that kind of code, you know that it's awful. Odersky's statement is not "purism"; far from it.
In Scala there is no piece of runtime data that is not an object, and there is no thing you can invoke methods on that is not an object. In Java neither of these statements in true; Java is a partially object-oriented language. In Java there are things which are not objects and there are methods which aren't on objects.
Newcomers to Scala often think of object Foo as some weird replacement for Java statics, but that's something you need to get past quickly. Instead think of Java's static methods as a non-OO wart and Scala's object Foo { ... } as something along these lines:
class SomeHiddenClass { ... }
val Foo = new SomeHiddenClass // the only instance of it
Here Foo is a value, not a type, and it really is an object. It can be passed to a method. It can extend some other class. For example:
abstract class AbFoo { def f:Int }
object Foo extends AbFoo { def f = 2 }
Now, finally, you can say
g(Foo)
It is true that a "companion object" for a class is a good place to put non-instance methods and data for the class. But that companion object is an object, so the usual rules and capabilities apply.
The fact that in Java you put such methods on non-objects -- limiting how they can be used -- is a liability, not a feature. It is certainly not OO.
I am not sure I completely buy that argument, but here is one possible reasoning.
To an object-oriented purist, everything should be an object, and all state should be encapsulated by objects. Any static member of a class is by definition state which exists outside of an object, because you can use it and manipulate it without instantiating an object. Thus, the lack of static class members makes for a more pure object-oriented language.
Well, with static members like methods you don't have any objects to create and nevertheless you can call such static methods. You only need the static classname in order to set the namespace for these methods, for example:
long timeNow = System.currentTimeMillis(); // no object creation
This rather gives a feeling like in procedural languages.
static members belongs to the Class not to the object while the main concept of oop lies among the relation between the individual objects of dirrefer Class.
A static method in Java is one that operates on the class itself, and doesn't need an Object to be created first. For example, this line:
int c = Integer.parseInt("5");
Integer.parseInt() is static because I didn't have to go Integer i = new Integer(); before using it; this isn't operating on any particular object that I've created, since it's always going to be the same, and is more like a typical procedural function call instead of an object-oriented method. It's more object-oriented if I have to create an object for every call and we encapsulate everything that way instead of allowing static to use methods as faux-procedural-functions.
There are several competing definitions of what exactly object-orientation means. However, there is one thing they all can agree on: dynamic dispatch is a fundamental part of the definition of OO.
Static methods are static (duh), not dynamic, ergo they are by definition not object-oriented.
And logically, a language that has a feature which isn't object-oriented is in some sense "less OO" than a language which doesn't have said feature.
Hi all I was wondering if I could modify and recompile a Java base class?
I would like to add functions to existing classes and be able to call these functions.
For example, I would like to add a function to java.lang.String, recompile it and use it for my project:
public char[] getInternalValue(){
return value;
}
I was wondering how do we go about doing that?
What you're referring to is called "monkey patching". It's possible in Java, but it isn't advisable and the results can be... uhh interesting. You can download the source for the String class, pop it into a JAR and prepend the bootclasspath with:
-Xbootclasspath/p:MonkeyPatchedString.jar
to replace the built-in String class with your own.
There's an interesting paper on this very subject here.
If you do it, you get incompatible with the java.lang.String class, and with all classes, relying on java.lang.String, which is very, very rarely a good idea.
A second problem could be the license. For self-studying it is perfectly fine, but if you publish your code (compiled or in source) you should read the license terms carefully before.
Since the String class is declared final, you can't even inherit from String, and implement your PacerierString, which seems useful at first sight. But there are so many people, who would have implemented their little helpers, that we would get a lot of SpecialString classes from everywhere.
A common practice would be people, writing a class Foo, and adding a method
public Foo toFoo () {
// some conversion for String representation of Foo
}
to their UniversalToolString.
You may, however, write a Wrapper, which contains a String. You might not pass your Wrapper to a method, which expects a String, but you would need to call its 'toString ()' method, if that happens to be a good candidate for that purpose.
Foo foo = new Foo ("foobar", 42);
foo.setMagic (foo.toString ().length);
Don't do that.
If you want to be evil, you can use reflection to access the byte array of a string. But of course there's no guarantee that that field will exist in the future as is... ok, it probably will, but caveat emptor.
Class.forName(boolean.class.getName());
This doesn't work in Java - the virtual machine slaps you with a ClassNotFoundException. I was in need for something like that because I wanted to reflect methods based on Strings that included the method signatures, like
public void doSomething(boolean yesWeCan, java.lang.String[] presidents);
At the end I came up with a custom 'ClassFactory' which translates the type Strings to class objects. This factory includes a lot of handlers for primitive and array type values.
The handler for array type objects is something like:
if (isArrayOfObjects) {
return Class.forName("L["+typeName.replace("[]", "")+";");
}
My question is - have I missed something in the Java 1.5+ API that might do the trick?
Edit
Thanks for your answers, it's not a surprise that Class.forName works pretty well with the wrapper classes. But I'm looking for a solution for all java types, including arrays and primitives. Thus my first line is not a typo. Some method signatures do have java primitives as parameters, I can't just use a wrapper class to reflect the method in a library, I really need the Class object for that type (like boolean).
Class<boolean> booleanClassObject = boolean.class;
works fine, as well as
String name = boolean.class.getName();
Perhaps you have a number of ifs:
if (type.equals("boolean")) {
return boolean.class;
} else if (type.equals("int")) {
return int.class;
} .. etc
The following will work:
Class.forName(Boolean.class.getName());
Auto(un)boxing should handle the translation to actual primitive. Although without seeing more of your code I can't be sure if this solves your problem.
It might be easier to actually create an array, and then ask for its .class. That's what I've done in the past.
Can you try using the Boolean wrapper class instead of the primitive boolean?
You are using boolean which is a primitive in java. You must use Boolean which is wrappaer class in java.
primitive type is a object and not a class. it can't getClassLoader and getClassName.
the below expression will be wrong.
boolean a = new boolean();