Well, that title along can't get the idea across but basically what I mean is that given some method m() in a class Base, which is not overridden in some subclass Derived, are the JIT compilers in current JVMs1 capable of "specializing"0 m() anyway when it makes sense, or will derived who inherit and don't override Base.m() share the same compiled code?
This specialization makes sense, where the derived class defines something that makes m() much simpler. For example and for the purposes of discussion, let's say m() calls another member function n() and in the derived class n() is defined such that when n() is inlined into m() the latter is greatly simplified.
To be concrete, consider following the two non-abstract methods in the following class (which are both m()-type methods, while the abstract methods are the corresponding n() methods):
public class Base {
abstract int divisor();
abstract boolean isSomethingEnabled();
int divide(int p) {
return p / divisor();
}
Object doSomething() {
if (isSomethingEnabled()) {
return slowFunction();
} else {
return null;
}
}
Both rely on abstract methods. Lets say you now have a Derived like this:
public class Derived extends Base {
final int divisor() {
return 2;
}
final boolean isSomethingEnabled() {
return false;
}
}
Now the effective behavior of the divide() and doSomething() methods are very simply, the divide is not a full division by an arbitrary number, but a simply halving that can be done with bit-operations. The doSomething() method always returns false. I assume that when the JIT goes to compile divide() or doSomething() if Derived is the only subclass, all is good: there exists (currently) only one possible implementation for the two abstract calls, and CHA will kick in and inline the only possible implementations and all is good.
In the more general case that other derived classes exist, however, it isn't clear to me if the JVM will only compile one2 version of the methods in Base with an invokevirtual call to the abstract methods, or if it is smart enough to say, "Hey, even though Derived doesn't override divisor() I should compile a version specifically for it 'cause it's going to be much simpler".
Of course, even without specialized recompilation aggressive inlining often makes it work out fine anyway (i.e., when you call divide() on a class that is known or even just likely to be a Derived, inlining is likely to give you the good implementation anyway, but, equally, there are plenty of cases where such inlining isn't done.
0 My specializing I don't mean anything specific beyond compiling another version of the function appropriate in some restricted domain, in the same sense that say inlining is a form of specialization to a specific call site, or in the same way that most functions are somewhat specialized to the current context (e.g., loaded classes, assumptions about nullness, etc).
1In particular, when one says "Can the JVM blah, blah?" one is usually talking about Hotspot, and I'm also mostly in Hotspot but also whether any other JVM can do this too.
2OK sure, you might have several version of a function, for on-stack-replacement, for different compiler levels, when deoptimization occurs, etc...
HotSpot JVM has at most one current, entrant version of compiled method. This is obvious from one-to-one relationship between Method and nmethod entities in the source code. However, there can be multiple non-entrant previous versions (e.g. nmethods compiled at lower tier and OSR stubs).
This single compiled version is often optimized for the most common case basing on run-time profiling. For example, when during profiling of Base.doSomething() JIT sees that isSomethingEnabled() is always invoked on Derived instance (even if there are more subclasses), it will optimize the call for the fast case, leaving an uncommon trap for a slow one. After this optimization doSomething() will look like
if (this.getClass() != Derived.class) {
uncommon_trap(); // this causes deoptimization
}
return false;
Profile data is collected separately for each branch and for each call site. This makes possible to optimize (specialize) a part of a method for one receiver, and the other part for a different receiver.
If two different receivers were detected during profiling, JIT can inline both callees guarded by a type check.
A virtual call with more than two receivers will be compiled using vtable lookup.
To see the method profile data use -XX:+PrintMethodData option available in debug builds of JVM.
No, my understanding is that the JVM would not specialize a method on its own but rather optimize the base class function if it finds during profile optimization that divisor() often resolves to a certain method.
Have you tried to print from diagnostics to see what happens?
Rather than trying to guess what the JIT is doing, you can take a peek
at what’s happening by turning on java command line flags:
-XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining (from Java JIT compiler inlining)
According to the OpenJDK Wiki:
Methods are often inlined. This increases the compiler's "horizon" of optimization.
Static, private, final, and/or "special" invocations are easy to inline.
Virtual (and interface) invocations are often demoted to "special" invocations, if the class hierarchy permits it. A dependency is registered in case further class loading spoils things.
Virtual (and interface) invocations with a lopsided type profile are compiled with an optimistic check in favor of the historically common type (or two types).
That is, for the two most frequent receiver types, the derived methods would be inlined into their caller (if small enough, which should be the case here), and unreachable branches pruned.
Also, if the base method is small enough for inlining into its caller, it will be optimized for that caller's two most frequent receiver types.
That is, the Hotspot JVM specializes code if it is small enough for inlining for the two most frequent receiver types of that call site.
The JVM doesn't define nor redefine types. It interprets running implementations of behaviors. It's the compiler, i.e., the source language that deals in types. The JVM is the low level, the "metal" of the Java universe. Types and their instances are instructions to create a series of observable events influenced by inputs. That series of inputs and observable events over time constitute what computer scientists call the "semantics" of a program.
It's up to the JVM to figure out ways to carry out those instructions while preserving the semantics. It will, at times, destroy a class structure entirely, in effect. Conceptually a class instance lives in heap memory with labeled attributes. For some period of time, until the semantics prohibit it because of some state change, the JVM might keep two active values in registers, not even in RAM, and ignore the whole rest of the defined class. Is that "specializing" the method?
No, it is not. There is no new definition, no new set of Java-level instructions, no ephemeral type in the JVM. There's just a temporary, compiled and optimized way in the moment to fulfill the instructions. When the optimization no longer works, or matters as much, the JVM even reverts to interpreting bytecode. And bytecode won't contain any new types, either. It's an assembly language, and redefining what the high-level code demands is above its pay grade.
Bottom line, the only types in the program are those mandated in the source code, not the bytecode or JVM. All the semantics come from the source.
Related
One of the most useful features of Java 8 are the new default methods on interfaces. There are essentially two reasons (there may be others) why they have been introduced:
Providing actual default implementations. Example: Iterator.remove()
Allowing for JDK API evolution. Example: Iterable.forEach()
From an API designer's perspective, I would have liked to be able to use other modifiers on interface methods, e.g. final. This would be useful when adding convenience methods, preventing "accidental" overrides in implementing classes:
interface Sender {
// Convenience method to send an empty message
default final void send() {
send(null);
}
// Implementations should only implement this method
void send(String message);
}
The above is already common practice if Sender were a class:
abstract class Sender {
// Convenience method to send an empty message
final void send() {
send(null);
}
// Implementations should only implement this method
abstract void send(String message);
}
Now, default and final are obviously contradicting keywords, but the default keyword itself would not have been strictly required, so I'm assuming that this contradiction is deliberate, to reflect the subtle differences between "class methods with body" (just methods) and "interface methods with body" (default methods), i.e. differences which I have not yet understood.
At some point of time, support for modifiers like static and final on interface methods was not yet fully explored, citing Brian Goetz:
The other part is how far we're going to go to support class-building
tools in interfaces, such as final methods, private methods, protected
methods, static methods, etc. The answer is: we don't know yet
Since that time in late 2011, obviously, support for static methods in interfaces was added. Clearly, this added a lot of value to the JDK libraries themselves, such as with Comparator.comparing().
Question:
What is the reason final (and also static final) never made it to Java 8 interfaces?
This question is, to some degree, related to What is the reason why “synchronized” is not allowed in Java 8 interface methods?
The key thing to understand about default methods is that the primary design goal is interface evolution, not "turn interfaces into (mediocre) traits". While there's some overlap between the two, and we tried to be accommodating to the latter where it didn't get in the way of the former, these questions are best understood when viewed in this light. (Note too that class methods are going to be different from interface methods, no matter what the intent, by virtue of the fact that interface methods can be multiply inherited.)
The basic idea of a default method is: it is an interface method with a default implementation, and a derived class can provide a more specific implementation. And because the design center was interface evolution, it was a critical design goal that default methods be able to be added to interfaces after the fact in a source-compatible and binary-compatible manner.
The too-simple answer to "why not final default methods" is that then the body would then not simply be the default implementation, it would be the only implementation. While that's a little too simple an answer, it gives us a clue that the question is already heading in a questionable direction.
Another reason why final interface methods are questionable is that they create impossible problems for implementors. For example, suppose you have:
interface A {
default void foo() { ... }
}
interface B {
}
class C implements A, B {
}
Here, everything is good; C inherits foo() from A. Now supposing B is changed to have a foo method, with a default:
interface B {
default void foo() { ... }
}
Now, when we go to recompile C, the compiler will tell us that it doesn't know what behavior to inherit for foo(), so C has to override it (and could choose to delegate to A.super.foo() if it wanted to retain the same behavior.) But what if B had made its default final, and A is not under the control of the author of C? Now C is irretrievably broken; it can't compile without overriding foo(), but it can't override foo() if it was final in B.
This is just one example, but the point is that finality for methods is really a tool that makes more sense in the world of single-inheritance classes (generally which couple state to behavior), than to interfaces which merely contribute behavior and can be multiply inherited. It's too hard to reason about "what other interfaces might be mixed into the eventual implementor", and allowing an interface method to be final would likely cause these problems (and they would blow up not on the person who wrote the interface, but on the poor user who tries to implement it.)
Another reason to disallow them is that they wouldn't mean what you think they mean. A default implementation is only considered if the class (or its superclasses) don't provide a declaration (concrete or abstract) of the method. If a default method were final, but a superclass already implemented the method, the default would be ignored, which is probably not what the default author was expecting when declaring it final. (This inheritance behavior is a reflection of the design center for default methods -- interface evolution. It should be possible to add a default method (or a default implementation to an existing interface method) to existing interfaces that already have implementations, without changing the behavior of existing classes that implement the interface, guaranteeing that classes that already worked before default methods were added will work the same way in the presence of default methods.)
In the lambda mailing list there are plenty of discussions about it. One of those that seems to contain a lot of discussion about all that stuff is the following: On Varied interface method visibility (was Final defenders).
In this discussion, Talden, the author of the original question asks something very similar to your question:
The decision to make all interface members public was indeed an
unfortunate decision. That any use of interface in internal design
exposes implementation private details is a big one.
It's a tough one to fix without adding some obscure or compatibility
breaking nuances to the language. A compatibility break of that
magnitude and potential subtlety would seen unconscionable so a
solution has to exist that doesn't break existing code.
Could reintroducing the 'package' keyword as an access-specifier be
viable. It's absence of a specifier in an interface would imply
public-access and the absence of a specifier in a class implies
package-access. Which specifiers make sense in an interface is unclear
- especially if, to minimise the knowledge burden on developers, we have to ensure that access-specifiers mean the same thing in both
class and interface if they're present.
In the absence of default methods I'd have speculated that the
specifier of a member in an interface has to be at least as visible as
the interface itself (so the interface can actually be implemented in
all visible contexts) - with default methods that's not so certain.
Has there been any clear communication as to whether this is even a
possible in-scope discussion? If not, should it be held elsewhere.
Eventually Brian Goetz's answer was:
Yes, this is already being explored.
However, let me set some realistic expectations -- language / VM
features have a long lead time, even trivial-seeming ones like this.
The time for proposing new language feature ideas for Java SE 8 has
pretty much passed.
So, most likely it was never implemented because it was never part of the scope. It was never proposed in time to be considered.
In another heated discussion about final defender methods on the subject, Brian said again:
And you have gotten exactly what you wished for. That's exactly what
this feature adds -- multiple inheritance of behavior. Of course we
understand that people will use them as traits. And we've worked hard
to ensure that the the model of inheritance they offer is simple and
clean enough that people can get good results doing so in a broad
variety of situations. We have, at the same time, chosen not to push
them beyond the boundary of what works simply and cleanly, and that
leads to "aw, you didn't go far enough" reactions in some case. But
really, most of this thread seems to be grumbling that the glass is
merely 98% full. I'll take that 98% and get on with it!
So this reinforces my theory that it simply was not part of the scope or part of their design. What they did was to provide enough functionality to deal with the issues of API evolution.
It will be hard to find and identify "THE" answer, for the resons mentioned in the comments from #EJP : There are roughly 2 (+/- 2) people in the world who can give the definite answer at all. And in doubt, the answer might just be something like "Supporting final default methods did not seem to be worth the effort of restructuring the internal call resolution mechanisms". This is speculation, of course, but it is at least backed by subtle evidences, like this Statement (by one of the two persons) in the OpenJDK mailing list:
"I suppose if "final default" methods were allowed, they might need rewriting from internal invokespecial to user-visible invokeinterface."
and trivial facts like that a method is simply not considered to be a (really) final method when it is a default method, as currently implemented in the Method::is_final_method method in the OpenJDK.
Further really "authorative" information is indeed hard to find, even with excessive websearches and by reading commit logs. I thought that it might be related to potential ambiguities during the resolution of interface method calls with the invokeinterface instruction and and class method calls, corresponding to the invokevirtual instruction: For the invokevirtual instruction, there may be a simple vtable lookup, because the method must either be inherited from a superclass, or implemented by the class directly. In contrast to that, an invokeinterface call must examine the respective call site to find out which interface this call actually refers to (this is explained in more detail in the InterfaceCalls page of the HotSpot Wiki). However, final methods do either not get inserted into the vtable at all, or replace existing entries in the vtable (see klassVtable.cpp. Line 333), and similarly, default methods are replacing existing entries in the vtable (see klassVtable.cpp, Line 202). So the actual reason (and thus, the answer) must be hidden deeper inside the (rather complex) method call resolution mechanisms, but maybe these references will nevertheless be considered as being helpful, be it only for others that manage to derive the actual answer from that.
I wouldn't think it is neccessary to specify final on a convienience interface method, I can agree though that it may be helpful, but seemingly the costs have outweight the benefits.
What you are supposed to do, either way, is to write proper javadoc for the default method, showing exactly what the method is and is not allowed to do. In that way the classes implementing the interface "are not allowed" to change the implementation, though there are no guarantees.
Anyone could write a Collection that adheres to the interface and then does things in the methods that are absolutely counter intuitive, there is no way to shield yourself from that, other than writing extensive unit tests.
We add default keyword to our method inside an interface when we know that the class extending the interface may or may not override our implementation. But what if we want to add a method that we don't want any implementing class to override? Well, two options were available to us:
Add a default final method.
Add a static method.
Now, Java says that if we have a class implementing two or more interfaces such that they have a default method with exactly same method name and signature i.e. they are duplicate, then we need to provide an implementation of that method in our class. Now in case of default final methods, we can't provide an implementation and we are stuck. And that's why final keyword isn't used in interfaces.
TL;DR: Given bytecode, how can I find out what classes and what methods get used in a given method?
In my code, I'd like to programmatically find all classes and methods having too generous access qualifiers. This should be done based on an analysis of inheritance, static usage and also hints I provide (e.g., using some home-brew annotation like #KeepPublic). As a special case, unused classes and methods will get found.
I just did something similar though much simpler, namely adding the final keyword to all classes where it makes sense (i.e., it's allowed and the class won't get proxied by e.g., Hibernate). I did it in the form of a test, which knows about classes to be ignored (e.g., entities) and complains about all needlessly non-final classes.
For all classes of mine, I want to find all methods and classes it uses. Concerning classes, there's this answer using ASM's Remapper. Concerning methods, I've found an answer proposing instrumentation, which isn't what I want just now. I'm also not looking for a tool like ucdetector which works with Eclipse AST. How can I inspect method bodies based on bytecode? I'd like to do it myself so I can programmatically eliminate unwanted warnings (which are plentiful with ucdetector when using Lombok).
Looking at the usage on a per-method basis, i.e. by analyzing all instructions, has some pitfalls. Besides method invocations, there might be method references, which will be encoded using an invokedynamic instruction, having a handle to the target method in its bsm arguments. If the byte code hasn’t been generated from ordinary Java code (or stems from a future version), you have to be prepared to possibly encounter ldc instructions pointing to a handle which would yield a MethodHandle at runtime.
Since you already mentioned “analysis of inheritance”, I just want to point out the corner cases, i.e. for
package foo;
class A {
public void method() {}
}
class B implements bar.If {
}
package bar;
public interface If {
void method();
}
it’s easy to overlook that A.method() has to stay public.
If you stay conservative, i.e. when you can’t find out whether B instances will ever end up as targets of the If.method() invocations at other places in your application, you have to assume that it is possible, you won’t find much to optimize. I think that you need at least inlining of bridge methods and the synthetic inner/outer class accessors to identify unused members across inheritance relationships.
When it comes class references, there are indeed even more possibilities, to make a per-instruction analysis error prone. They may not only occur as owner of member access instructions, but also for new, checkcast, instanceof and array specific instructions, annotations, exception handlers and, even worse, within signatures which may occur at member references, annotations, local variable debugging hints, etc. The ldc instruction may refer to classes, producing a Class instance, which is actually used in ordinary Java code, e.g. for class literals, but as said, there’s also the theoretical possibility to produce MethodHandles which may refer to an owner class, but also have a signature bearing parameter types and a return type, or to produce a MethodType representing a signature.
You are better off analyzing the constant pool, however, that’s not offered by ASM. To be precise, a ClassReader has methods to access the pool, but they are actually not intended to be used by client code (as their documentation states). Even there, you have to be aware of pitfalls. Basically, the contents of a CONSTANT_Utf8_info bears a class or signature reference if a CONSTANT_Class_info resp. the descriptor index of a CONSTANT_NameAndType_info or a CONSTANT_MethodType_info points to it. However, declared members of a class have direct references to CONSTANT_Utf8_info pool entries to describe their signatures, see Methods and Fields. Likewise, annotations don’t follow the pattern and have direct references to CONSTANT_Utf8_info entries of the pool assigning a type or signature semantic to it, see enum_const_value and class_info_index…
How does method/field visibility impact on method inlining in Java?
The case I have in mind is something like a public getter for a private field:
private Thing blah;
public Thing getBlah() {
return blah;
}
There are several issues that arise here.
For one, does the Java compiler itself do any inlining? This question seems to be answered variously, with some saying yes and some saying no. I don't know whether that's because it used not to do any inlining but now does, or whether it's just that some people are right and some people are wrong...
Now, if it does do some inlining, am I right in thinking that it can't possibly inline getBlah() calls? They would be an obvious place for inlining to be useful, because the method is very simple, and the overhead of invoking a method is as big as the code for the method itself. But if it got inlined by the compiler, you'd end up with bytecode that accessed a private field directly; and surely the JVM would then complain? (This would apply even if this method were static final.)
Secondly, what about the JIT compiler? As far as I can see, this problem doesn't apply when it comes to inlining at that level. Once it's producing native code, the JVM has already done its checks, and confirmed that I can invoke the method (because it's public); so it can then generate native code that inlines the call, without any visibility issues... yes?
The javac compiler (and any valid java compiler) will not and can not inline getters; think about it: You could extend a class from that class and overwrite the getter. And yes if a compiler would overzealously inline that access it would not pass the verifier (well at least it should not pass the verifier, but they don't verify everything - in java 1.3 you could even make main() private and it would still work... likewise there used to be an -O option in javac that did sometimes screw your code).
The JIT is a whole other beast; it knows (well at least nowadays) at any time if there is an overwite for a method or not. Even if a class is later loaded that overwrites the getter, it can deoptimize already JIT'd methods to refelect alterations on the inhertance tree (thats one of the optimizations AOT compilers lack the information for).
Thus it can safely inline whatever it wants. It also doesn't need to artificially uphold access modfiers, because there is no such thing in the compiled machine code and again it knows what is a vaild code transformatiom (and since getters are so common its also a low hanging fruit for the JIT to optimize).
Edit: To make it absolutely clear, above paragraphs address potentially virtual methods; specifically those that are not private, static or final. Javac could perform inlining in some cases; because it could prove that no override can exist for those. It would be a pointless undertaking in face of the fact that the JIT also does it, and it does a far better job at it.
javac does not inline methods, even as simple as getBlah() and setBlah()
As to HotSpot JVM, JIT compiler does inline all such methods unless it reaches the maximum level of inlining (-XX:MaxInlineLevel)
JIT equally treats public and private methods in terms of inlining. Access modifiers does not generally affect inlining unless some very specific cases.
Whether or not any particular Java compiler -- Oracle's, for instance -- performs any inlining is an implementation detail that you would be better off ignoring. A future generation of your chosen compiler or an alternative compiler might operate differently than the one you happen to be looking at now.
To the extent that a Java compiler did perform inlining, however, it could inline only private methods and constructors. Anything else is a candidate for access from (unknowable) other classes.
A JIT compiler, on the other hand, can do pretty much anything it wants, including inlining public methods. It is responsible for any adjustments that may be needed when new classes are loaded. Beans-style accessor methods are a particularly likely thing for a JIT to optimize, they being such a common pattern.
Some classes in the standard Java API are treated slightly different from other classes. I'm talking about those classes that couldn't be implemented without special support from the compiler and/or JVM.
The ones I come up with right away are:
Object (obviously) as it, among other things doesn't have a super class.
String as the language has special support for the + operator.
Thread since it has this magical start() method despite the fact that there is no bytecode instruction that "forks" the execution.
I suppose all classes like these are in one way or another mentioned in the JLS. Correct me if I'm wrong.
Anyway, what other such classes exist? Is there any complete list of "glorified classes" in the Java language?
There are a lot of different answers, so I thought it would be useful to collect them all (and add some):
Classes
AutoBoxing classes - the compiler only allows for specific classes
Class - has its own literals (int.class for instance). I would also add its generic typing without creating new instances.
String - with it's overloaded +-operator and the support of literals
Enum - the only class that can be used in a switch statement (soon a privilege to be given to String as well). It does other things as well (automatic static method creation, serialization handling, etc.), but those could theoretically be accomplished with code - it is just a lot of boilerplate, and some of the constraints could not be enforced in subclasses (e.g. the special subclassing rules) but what you could never accomplish without the priviledged status of an enum is include it in a switch statement.
Object - the root of all objects (and I would add its clone and finalize methods are not something you could implement)
References: WeakReference, SoftReference, PhantomReference
Thread - the language doesn't give you a specific instruction to start a thread, rather it magically applies it to the start() method.
Throwable - the root of all classes that can work with throw, throws and catch, as well as the compiler understanding of Exception vs. RuntimeException and Error.
NullPointerException and other exceptions such as ArrayIndexOutOfBounds which can be thrown by other bytecode instructions than athrow.
Interfaces
Iterable - the only interface that can be used in an enhanced for loop
Honorable mentions goes to:
java.lang.reflect.Array - creating a new array as defined by a Class object would not be possible.
Annotations They are a special language feature that behaves like an interface at runtime. You certainly couldn't define another Annotation interface, just like you can't define a replacement for Object. However, you could implement all of their functionality and just have another way to retrieve them (and a whole bunch of boilerplate) rather than reflection. In fact, there were many XML based and javadoc tag based implementations before annotations were introduced.
ClassLoader - it certainly has a privileged relationship with the JVM as there is no language way to load a class, although there is a bytecode way, so it is like Array in that way. It also has the special privilege of being called back by the JVM, although that is an implementation detail.
Serializable - you could implement the functionality via reflection, but it has its own privileged keyword and you would spend a lot of time getting intimate with the SecurityManager in some scenarios.
Note: I left out of the list things that provide JNI (such as IO) because you could always implement your own JNI call if you were so inclined. However, native calls that interact with the JVM in privileged ways are different.
Arrays are debatable - they inherit Object, have an understood hierarchy (Object[] is a supertype of String[]), but they are a language feature, not a defined class on its own.
Class, of course. It has its own literals (a distinction it shares with String, BTW) and is the starting point of all that reflection magic.
sun.misc.unsafe is the mother of all dirty, spirit-of-the-language-breaking hacks.
Enum. You're not allowed to subclass it, but the compiler can.
Many things under java.util.concurrent can be implemented without JVM support, but they would be a lot less efficient.
All of the Number classes have a little bit of magic in the form of Autoboxing.
Since the important classes were mentioned, I'll mention some interfaces:
The Iterable interface (since 1.5) - it allows an object to participate in a foreach loop:
Iterable<Foo> iterable = ...;
for (Foo foo : iterable) {
}
The Serializable interface has a very special meaning, different from a standard interface. You can define methods that will be taken into account even though they are not defined in the interface (like readResolve()). The transient keyword is the language element that affects the behaviour of Serializable implementors.
Throwable, RuntimeException, Error
AssertionError
References WeakReference, SoftReference, PhantomReference
Enum
Annotation
Java array as in int[].class
java.lang.ClassLoader, though the actual dirty work is done by some unmentioned subclass (see 12.2.1 The Loading Process).
Not sure about this. But I cannot think of a way to manually implement IO objects.
There is some magic in the System class.
System.arraycopy is a hook into native code
public static native void arraycopy(Object array1, int start1,
Object array2, int start2, int length);
but...
/**
* Private version of the arraycopy method used by the jit
* for reference arraycopies
*/
private static void arraycopy(Object[] A1, int offset1,
Object[] A2, int offset2, int length) {
...
}
Well since the special handling of assert has been mentioned. Here are some more Exception types which have special treatment by the jvm:
NullPointerException
ArithmeticException.
StackOverflowException
All kinds of OutOfMemoryErrors
...
The exceptions are not special, but the jvm uses them in special cases, so you can't implement them yourself without writing your own jvm. I'm sure that there are more special exceptions around.
Most of those classes isn't really implemented with 'special' help from the compiler or JVM. Object does register some natives which poke around the internal JVM structures, but you can do that for your own classes as well. (I admit this is subject to semantics, "calls a native defined in the JVM" can be considered as special JVM support.)
What /is/ special is the behaviour of the 'new', and 'throw' instructions in how they initialise these internal structures.
Annotations and numbers are pretty much all-out freaky though.
Is there a concept of inline functions in java, or its replaced something else? If there is, how is it used? I've heard that public, static and final methods are the inline functions. Can we create our own inline function?
In Java, the optimizations are usually done at the JVM level. At runtime, the JVM perform some "complicated" analysis to determine which methods to inline. It can be aggressive in inlining, and the Hotspot JVM actually can inline non-final methods.
The java compilers almost never inline any method call (the JVM does all of that at runtime). They do inline compile time constants (e.g. final static primitive values). But not methods.
For more resources:
Article: The Java HotSpot Performance Engine: Method Inlining Example
Wiki: Inlining in OpenJDK, not fully populated but contains links to useful discussions.
No, there is no inline function in java. Yes, you can use a public static method anywhere in the code when placed in a public class. The java compiler may do inline expansion on a static or final method, but that is not guaranteed.
Typically such code optimizations are done by the compiler in combination with the JVM/JIT/HotSpot for code segments used very often. Also other optimization concepts like register declaration of parameters are not known in java.
Optimizations cannot be forced by declaration in java, but done by compiler and JIT. In many other languages these declarations are often only compiler hints (you can declare more register parameters than the processor has, the rest is ignored).
Declaring java methods static, final or private are also hints for the compiler. You should use it, but no garantees. Java performance is dynamic, not static. First call to a system is always slow because of class loading. Next calls are faster, but depending on memory and runtime the most common calls are optimized withinthe running system, so a server may become faster during runtime!
Java does not provide a way to manually suggest that a method should be inlined. As #notnoop says in the comments, the inlining is typically done by the JVM at execution time.
What you said above is correct. Sometimes final methods are created as inline, but there is no other way to explicitly create an inline function in java.
Well, there are methods could be called "inline" methods in java, but depending on the jvm. After compiling, if the method's machine code is less than 35 byte, it will be transferred to a inline method right away, if the method's machine code is less than 325 byte, it could be transferred into a inline method, depending on the jvm.
Real life example:
public class Control {
public static final long EXPIRED_ON = 1386082988202l;
public static final boolean isExpired() {
return (System.currentTimeMillis() > EXPIRED_ON);
}
}
Then in other classes, I can exit if the code has expired. If I reference the EXPIRED_ON variable from another class, the constant is inline to the byte code, making it very hard to track down all places in the code that checks the expiry date. However, if the other classes invoke the isExpired() method, the actual method is called, meaning a hacker could replace the isExpired method with another which always returns false.
I agree it would be very nice to force a compiler to inline the static final method to all classes which reference it. In that case, you need not even include the Control class, as it would not be needed at runtime.
From my research, this cannot be done. Perhaps some Obfuscator tools can do this, or, you could modify your build process to edit sources before compile.
As for proving if the method from the control class is placed inline to another class during compile, try running the other class without the Control class in the classpath.
so, it seems there arent, but you can use this workaround using guava or an equivalent Function class implementation, because that class is extremely simple, ex.:
assert false : new com.google.common.base.Function<Void,String>(){
#Override public String apply(Void input) {
//your complex code go here
return "weird message";
}}.apply(null);
yes, this is dead code just to exemplify how to create a complex code block (within {}) to do something so specific that shouldnt bother us on creating any method for it, AKA inline!
Java9 has an "Ahead of time" compiler that does several optimizations at compile-time, rather than runtime, which can be seen as inlining.