With JDK7, the reflection API has changed and now the methods returned by getDeclaredMethods() are not returned in the order in which they are declared in the source file.
Now my question is, does the .class file generated by javac contains methods in the same order in which they were defined in the source file OR it can write methods in random order too?
The Binary Compatibility chapter of the Java Language Specification is explicit about the fact that reordering of elements in the class files is permitted:
[...] here is a list of some important binary compatible changes that the Java programming language supports:
[...]
Reordering the fields, methods, or constructors in an existing type declaration.
[...]
Reordering the list of direct superinterfaces of a class or interface.
That means that the order in which they appear in the .class file is not dictated by the specifications. If you want to rely on it, you have to either (1) know for a fact that your specific implementation uses the same order as the definition order (testing it, like you've done, is a good idea but does not guarantee anything), or (2) change the order yourself.
Class.getDeclaredMethods API is clear about this "...The elements in the array returned are not sorted and are not in any particular order...". Most likely the reason of that is that javac is not obliged to generate methods in .class in any particular order.
Related
I have some (maybe) strange requirements - I wanted to detect definitions of local (method) variables of a given interface name. When finding such a variable I would like to detect which methods (set/get*) will be called on this variable.
I tried Javassist without luck, and now I have a deeper look into ASM, but not sure if it is possible what I wanted.
The reason for this is that I like to generated a dependency graph with GraphViz of beans that depend on the same data structure.
If this thing is possible could somebody please give me a hint on how it could be done? Maybe there are other Frameworks that could do?
01.09.2015
To make things more clear:
The interface is self written - the target of the whole action is to create a dependency graph in the first step automatically - later on a graphical editor should be implemented that is based on the dependencies.
I wonder how FindBugs/PMD work, because they also use the byte code and detect for example null pointer calls (variable not initialized and method will be called on it). So I thought that I could implement my idea in the same way. The whole code is Spring based - maybe this opens another solution to the point? Last but not least I could work on a source-jar?
While thinging about the problem - would it be possible via ASM/javassist to detect all available methods from the interface and find calls to them in the other classes?
I’m afraid, what you want to do is not possible. In compiled Java code, there are no local variables in the form you have in the source code. Methods use stack frames which have memory reserved for local variables, which is addressed by a numerical index. The type is implied by what instructions write to it and may change throughout the method’s code as the memory may get reused for different variables having a disjunct scope. The names on the other hand are completely irrelevant.
When bytecode gets verified, the effect of all instructions to the stack frame will get modeled to infer the type of each stack frame slot at each point of the execution so that the validity of all operations can be checked. Starting with class file version 50, there will be StackMapTable attributes aiding the process by containing explicit type information, but only for code with branches. For sequential code, the type of variables still has to be derived by inference.
These inferred types are not necessarily the declared types. E.g., on the byte code level, there will be no difference between
CharSequence cs="foo";
cs.charAt(0);
and
String s="foo";
((CharSequence)s).charAt(0);
In both cases, there will be a storage of a String constant into a local variable followed by the invocation of an interface method. The inferred type will be String in both cases and the invocation of a CharSequence method considered valid as String implements CharSequence.
This disproves the idea of detecting that there is a local variable declared using the CharSequence (interface) type, as the actual declared type is irrelevant and not stored in the regular byte code.
There are, however, debugging attributes containing information about the local variables, see the LocalVariableTable attribute and libraries like ASM will tell you about the declarations if such information is present. But you can’t rely on these optional information. E.g. Oracle’s JRE libraries are by default shipped without them.
I don't sure I understood exacly what you want but .
you can use implement on each object ,
evry object that have getter you can implement it with class called getable .
and then you could do stuff only on object that have the function that you implement from the class getable .
https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html
I have started study about nio.2 in java 8 from java documentation. When I study about java.nio.file.Path, java documentation's first line is
The Path class, introduced in the Java SE 7 release.
which mean Path is a class, but when I look here I found that Path is an interface.
So why java documentation says that it is a class.
My another doubt is if Path is an interface then how Path methods (like getRoot() isAbsolute() and all other) work, because there is no implementation of methods of Path interface.
I know asking two different question in one statement is cumbersome but I have no idea how these two questions can be separated.
Edit: This question can't be duplicate of this, because in this question the questioner asked for implementation of Path interface, but here I'm asking how methods of this interface works, I mean is it internally executed by the JVM or any other mechanism is used to execute them.
Path is an ordinary interface that is implemented like any other interface by a concrete class that declares to implement it and provides concrete methods for the abstract methods of the interface. So there’s nothing special with the methods of Path. As the linked question explains, there are ordinary implementations of this interface.
You shouldn’t get confused because it is called “class” in the documentation. While class in the narrowest sense is a type distinct from interface or enums, these types are all classes in the broadest meaning of the term. This is reflected by the fact that they all are stored within a class file and loaded via an operation name loadClass on a ClassLoader. At these places, no distinction between interfaces and classes is made. From this point of view, interfaces and enums are just classes with special properties (and similar, annotations are interfaces with special properties).
In documentations it makes sense to use the term “class” in the broader sense when the way you use it doesn’t differ, i.e. you are calling methods on a Path instance without having to care about whether the Path type is an interface. A difference has to be emphasized only when the reader is the one who has to implement it.
Path is an interface because the concrete implementation depends on the underlying file system. The methods are in classes which implement the interface, these are platform-dependent.
Note that you never contruct a Path object with new, but use a method like Paths.get, which returns an instance of the appropriate class.
For example, in Oracle's implementation, paths in windows are implemented by sun.nio.fs.WindowsPath (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/nio/fs/WindowsPath.java)
I have a java template class, of which I would like to modify a single String field.
I can instantiate an object of that class, get to its corresponding Class object, and modify the field using reflection, so far so good.
But how do I actually save the bytecode to the filesystem?
Since I think that if I get to the ClassLoader of the original template class, get to the InputStream and try to save to a file I will get the original (i.e. unmodified) class implementation. Is it so?
Ideally I would also need to change the class name to something more meaningful.
Can both things be done using pure java in the first place?
Or do I have to resort to external libraries?
When you modify a field using reflection, you're not changing anything about the class itself. It's just a fancy way of setting a variable. So there's no changed bytecode to worry about in the first place.
Anyway, AFAIK you can't easily get access to bytecode at runtime. The JVM creates classes from classfiles (either from files or in memory data) but once the class is loaded, there's no particular reason to keep the data around. Most likely, it will only keep an optimized representation that doesn't necessary correspond to the original classfile.
I think there are some APIs like Java agent that deal with bytecode at runtime, but it's not clear how well they work, partly because the JVM does optimize things.
Find an assembler/disassembler pair. Disassemble the class file, replace the string value, and compile back to class file. Note that the string constant can be referenced from several points, so probably you have to add a constant and change only one reference. If the new string value has the same length as the old one (in UTF-8 encoding), then you just replace constant with a binary file editor. If length are different, replacing would destroy the whole classfile structure.
I have a file Test.java and the following code inside it.
public class Abcd
{
//some code here
}
Now the class does not compile, but when I remove the public modifier , it compiles fine.
What is the reasoning behind Java allowing us to compile a class name that is different from the file name when it is not public.
I know it is a newbie question, but I'm not able to find a good explanation.
The rationale is to allow more than one top-level class per .java file.
Many classes—such as event listeners—are of local use only and the earliest versions of Java did not support nested classes. Without this relaxation of the "filename = class name" rule, each and every such class would have required its own file, with the unavoidable result of endless proliferation of small .java files and the scattering of tightly coupled code.
As soon as Java introduced nested classes, the importance of this rule waned significantly. Today you can go through many hundreds of Java files, never chancing upon one which takes advantage of it.
The reason is the same as for the door plates. If some person officially resides in the office (declared public) his/her name must be on the door tag. Like "Alex Jones" or "Detective Colombo". If somebody just visits the room, talks to an official or cleans the floor, their name does not have to be officially put on the door. Instead, the door can read "Utilities" or "Meeting room".
The Java specification states you can only have at most one public class per file. In this case, the class name should match the file name. All non-public classes are allowed to have any name, regardless of the file name.
I think allowing them is a prerequisite for nested classes. Anonymous Classes in particular dramatically reduce the number of .java files required. Without support for this, you would need lots of single method interface implementations in their own separate files from the main class they are used in. (I'm thinking of action listeners in particular)
There is a good explanation of all nested classes in the Nested Classes Java tutorial on Oracle's website, which has examples of each. It also has a reason they are useful, which I'll quote:
Why Use Nested Classes?
Compelling reasons for using nested classes include the following:
It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.
It increases encapsulation: Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be
declared private. By hiding class B within class A, A's members can be
declared private and B can access them. In addition, B itself can be
hidden from the outside world.
It can lead to more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is
used.
(emphasis mine)
I am not familiar with Java spec back in the early days, but a quick search shows inner classes were added in Java 1.1.
I look at it the other way round. The natural state of affairs would be for the programmer to pick both the class name and the file name independently. Probably in order to simplify finding public classes from outside a package during compilation, there is a special restriction that a public class be in a file with the corresponding name.
Note that Java is case-sensitive, but the filesystem need not be. If the file's base name is "abcd", but the class is "Abcd", would that conform to the rule on a case-insensitive filesystem? Certainly not when ported to a case-sensitive one.
Or suppose you happened to have a class called ABCD, and a class Abcd (let's not get into that being a bad idea: it could happen) and the program is ported to a case insensitive filesystem. Now you not only have to rename files, but also classes, oops!
Or what if there is no file? Suppose you have a Java compiler which can take input on standard input. So then the class has to be named "StandardInput"?
If you rationally explore the implications of requiring file names to follow class names, you will find that it's a bad idea in more than one way.
Also one other point that many answers missed to point out is that without the public declaration, the JVM would never know which classes' main method needs to be invoked. All classes declared in one .java file can all have main methods, but the main method is run on only the class marked as public. HTH
Because of a java file can contains more than one class, it may have two classes in one java file. But a java file have to contain a class as the same name as file name if it contains a public class.
When i want to create a java class it is generating automatically a file with the same name of class.
But when it generate a class, it can change the file name different than class name..
Am i missing something?
(source: screencast.com)
Quoting the section 7.6 Top Level Type Declarations from the Java Language Specification:
When packages are stored in a file
system (§7.2.1), the host system
may choose to enforce the restriction
that it is a compile-time error if a
type is not found in a file under a
name composed of the type name plus an
extension (such as .java or .jav)
if either of the following is true:
The type is referred to by code in other compilation units of the package
in which the type is declared.
The type is declared public (and therefore is potentially accessible
from code in other packages).
This restriction implies that there
must be at most one such type per
compilation unit. This restriction
makes it easy for a compiler for the
Java programming language or an
implementation of the Java virtual
machine to find a named class within a
package; for example, the source code
for a public type wet.sprocket.Toad
would be found in a file Toad.java
in the directory wet/sprocket, and
the corresponding object code would be
found in the file Toad.class in the
same directory.
When packages are stored in a database
(§7.2.2), the host system must
not impose such restrictions. In
practice, many programmers choose to
put each class or interface type in
its own compilation unit, whether or
not it is public or is referred to by
code in other compilation units.
Because the language designers say so. It really is that simple. It's a convention and they force you to follow it.
The language specification itself does not dictate this (I've just had a look, and can find no reference to it), but it's generally enforced by tools. It makes it considerably easier for tools' dependency management, since it knows where to look for class B if class A has a reference to it. The convention extends to the directory structure echoing the package structure, but again, this is just a convention.
If I can change the world I wish c# designers also do that.
How much time can be saved from forcing guys to not create file classes.cs and put ALL code in it. Isn't it such as requirement of braces for If. Why language force me do that silly thing:
if (true)
{
}
instead of
if true
{
}
:-)