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.
Related
Heads up: I'm writing some of this from memory so I may have some of the concepts incorrect.
Java has the ability to write an anonymous function. This is useful when you have a listener interface for some kind of event. As an example:
button.setOnClickListener(new View.OnClickListener(View v) {
#Override
public void onClick(View v) {
// handle the action here
}
});
The anonymous listener will be compiled as a class that is called something like OnClickListener$1.class. This is an underlying design decision of the Java language. Everything is an object, even anonymous functions.
This becomes an issue when you want to write a more functionally driven code base. The large amount of anonymous classes creates a large class count, which can be a problem on constrained platforms such as Android.
In Kotlin functions are much more first class from a source code point of view. My question is, does Kotlin compile these functions down to byte code more efficiently than Java does with anonymous classes or will I run into the same issues as the large class count in Java?
Thanks,
The short answer is yes, the Kotlin inline functions are quite cheap.
When an inline function call is compiled, the lambdas passed to the call get inlined into the function body, which is in turn inlined at the call site. This allows the compiler not to generate any additional classes or methods for the lambda bodies.
One of the slides about Kotlin constructs compilation by #yole.
Unfortunately, I found the record only in Russian. The other slides are also of some interest, you can find more about non-inlined lambdas there.
In general, the Kotlin code that uses inline functions with lambdas works faster than the identical Java code with lambdas or Streams. All the code binding is done at compile-time, and there is no runtime overhead of virtual method calls, nor increased methods count, which matters for Android.
The downside of excessive inlining is the code size growth: the common part of the bytecode of an inline function body gets actually duplicated at the call sites. Also, inlining complicates debugging, because the line numbers and the call stack of the code will differ from what was in the source file. Though the IDE support can help here.
I would recommend you to experiment with inline functions yourself: you can easily inspect the resulting bytecode; and, of course, do some benchmarking of your particular use cases where performance matters.
Kotlin has an inline keyword. If you use this keyword, not only does it inline the function but you can treat the lambda body as if it was just a nested scope level, so that you can return from it!
Example (straight from the docs)
fun foo() {
inlineFunction {
return // OK: the lambda is inlined
}
}
Check out the docs for more:
https://kotlinlang.org/docs/reference/inline-functions.html
Edit:
To clarify your exact question about performance, this is the first paragraph from the docs:
Using higher-order functions imposes certain runtime penalties: each function is an object, and it captures a closure, i.e. those variables that are accessed in the body of the function. Memory allocations (both for function objects and classes) and virtual calls introduce runtime overhead.
But it appears that in many cases this kind of overhead can be eliminated by inlining the lambda expressions.
So as far as I can tell yes, it will inline the function and remove any overhead that would otherwise be imposed.
However, this seems to only apply to functions you declare as inline.
I was reading through Java-The Complete Reference,and then I encountered this statement which says that-
Methods declared as final can sometimes provide a performance enhancement:
Reason given is-
The compiler is free to inline calls to them because it “knows” they
will not be overridden by a subclass.
When a small final method is called, often the Java compiler can copy
the bytecode
for the subroutine directly inline with the compiled code of the calling method,
thus eliminating the costly overhead associated with a method call.
Inlining is only an option with final methods.
I am not able to understand the second point.Can somebody please explain?What exactly is Inlining?
I'm sure you all know the behaviour I mean - code such as:
Thread thread = new Thread();
int activeCount = thread.activeCount();
provokes a compiler warning. Why isn't it an error?
EDIT:
To be clear: question has nothing to do with Threads. I realise Thread examples are often given when discussing this because of the potential to really mess things up with them. But really the problem is that such usage is always nonsense and you can't (competently) write such a call and mean it. Any example of this type of method call would be barmy. Here's another:
String hello = "hello";
String number123AsString = hello.valueOf(123);
Which makes it look as if each String instance comes with a "String valueOf(int i)" method.
Basically I believe the Java designers made a mistake when they designed the language, and it's too late to fix it due to the compatibility issues involved. Yes, it can lead to very misleading code. Yes, you should avoid it. Yes, you should make sure your IDE is configured to treat it as an error, IMO. Should you ever design a language yourself, bear it in mind as an example of the kind of thing to avoid :)
Just to respond to DJClayworth's point, here's what's allowed in C#:
public class Foo
{
public static void Bar()
{
}
}
public class Abc
{
public void Test()
{
// Static methods in the same class and base classes
// (and outer classes) are available, with no
// qualification
Def();
// Static methods in other classes are available via
// the class name
Foo.Bar();
Abc abc = new Abc();
// This would *not* be legal. It being legal has no benefit,
// and just allows misleading code
// abc.Def();
}
public static void Def()
{
}
}
Why do I think it's misleading? Because if I look at code someVariable.SomeMethod() I expect it to use the value of someVariable. If SomeMethod() is a static method, that expectation is invalid; the code is tricking me. How can that possibly be a good thing?
Bizarrely enough, Java won't let you use a potentially uninitialized variable to call a static method, despite the fact that the only information it's going to use is the declared type of the variable. It's an inconsistent and unhelpful mess. Why allow it?
EDIT: This edit is a response to Clayton's answer, which claims it allows inheritance for static methods. It doesn't. Static methods just aren't polymorphic. Here's a short but complete program to demonstrate that:
class Base
{
static void foo()
{
System.out.println("Base.foo()");
}
}
class Derived extends Base
{
static void foo()
{
System.out.println("Derived.foo()");
}
}
public class Test
{
public static void main(String[] args)
{
Base b = new Derived();
b.foo(); // Prints "Base.foo()"
b = null;
b.foo(); // Still prints "Base.foo()"
}
}
As you can see, the execution-time value of b is completely ignored.
Why should it be an error? The instance has access to all the static methods. The static methods can't change the state of the instance (trying to is a compile error).
The problem with the well-known example that you give is very specific to threads, not static method calls. It looks as though you're getting the activeCount() for the thread referred to by thread, but you're really getting the count for the calling thread. This is a logical error that you as a programmer are making. Issuing a warning is the appropriate thing for the compiler to do in this case. It's up to you to heed the warning and fix your code.
EDIT: I realize that the syntax of the language is what's allowing you to write misleading code, but remember that the compiler and its warnings are part of the language too. The language allows you to do something that the compiler considers dubious, but it gives you the warning to make sure you're aware that it could cause problems.
They cannot make it an error anymore, because of all the code that is already out there.
I am with you on that it should be an error.
Maybe there should be an option/profile for the compiler to upgrade some warnings to errors.
Update: When they introduced the assert keyword in 1.4, which has similar potential compatibility issues with old code, they made it available only if you explicitly set the source mode to "1.4". I suppose one could make a it an error in a new source mode "java 7". But I doubt they would do it, considering that all the hassle it would cause. As others have pointed out, it is not strictly necessary to prevent you from writing confusing code. And language changes to Java should be limited to the strictly necessary at this point.
Short answer - the language allows it, so its not an error.
The really important thing, from the compiler's perspective, is that it be able to resolve symbols. In the case of a static method, it needs to know what class to look in for it -- since it's not associated with any particular object. Java's designers obviously decided that since they could determine the class of an object, they could also resolve the class of any static method for that object from any instance of the object. They choose to allow this -- swayed, perhaps, by #TofuBeer's observation -- to give the programmer some convenience. Other language designers have made different choices. I probably would have fallen into the latter camp, but it's not that big of a deal to me. I probably would allow the usage that #TofuBeer mentions, but having allowed it my position on not allowing access from an instance variable is less tenable.
Likely for the same logical that makes this not an error:
public class X
{
public static void foo()
{
}
public void bar()
{
foo(); // no need to do X.foo();
}
}
It isn't an error because it's part of the spec, but you're obviously asking about the rationale, which we can all guess at.
My guess is that the source of this is actually to allow a method in a class to invoke a static method in the same class without the hassle. Since calling x() is legal (even without the self class name), calling this.x() should be legal as well, and therefore calling via any object was made legal as well.
This also helps encourage users to turn private functions into static if they don't change the state.
Besides, compilers generally try to avoid declaring errors when there is no way that this could lead to a direct error. Since a static method does not change the state or care about the invoking object, it does not cause an actual error (just confusion) to allow this. A warning suffices.
The purpose of the instance variable reference is only to supply the type which encloses the static. If you look at the byte code invoking a static via instance.staticMethod or EnclosingClass.staticMethod produces the same invoke static method bytecode. No reference to the instance appears.
The answer as too why it's in there, well it just is. As long as you use the class. and not via an instance you will help avoid confusion in the future.
Probably you can change it in your IDE (in Eclipse Preferences -> Java -> Compiler -> Errors/Warnings)
There's not option for it. In java (like many other lang.) you can have access to all static members of a class through its class name or instance object of that class. That would be up to you and your case and software solution which one you should use that gives you more readability.
It's pretty old topic but still up-to-date and surprisingly bringing higher impact nowadays. As Jon mentioned, it might be just a mistake Java's designers made at the very beginning. But I wouldn't imagine before it can have impact on security.
Many coders know Apache Velocity, flexible and powerful template engine. It's so powerful that it allows to feed template with a set of named objects - stricly considered as objects from programming language (Java originally). Those objects can be accessed from within template like in programming language so for example Java's String instance can be used with all its public fields, properties and methods
$input.isEmpty()
where input is a String, runs directly through JVM and returns true or false to Velocity parser's output). So far so good.
But in Java all objects inherit from Object so our end-users can also put this to the template
$input.getClass()
to get an instance of String Class.
And with this reference they can also call a static method forName(String) on this
$input.getClass().forName("java.io.FileDescriptor")
use any class name and use it to whatever web server's account can do (deface, steal DB content, inspect config files, ...)
This exploit is somehow (in specific context) described here: https://github.com/veracode-research/solr-injection#7-cve-2019-17558-rce-via-velocity-template-by-_s00py
It wouldn't be possible if calling static methods from reference to the instance of class was prohibited.
I'm not saying that a particular programming framework is better than the other one or so but I just want to put a comparison. There's a port of Apache Velocity for .NET. In C# it's not possible to call static methods just from instance's reference what makes exploit like this useless:
$input.GetType().GetType("System.IO.FileStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
I just consider this:
instanceVar.staticMethod();
to be shorthand for this:
instanceVar.getClass().staticMethod();
If you always had to do this:
SomeClass.staticMethod();
then you wouldn't be able to leverage inheritance for static methods.
That is, by calling the static method via the instance you don't need to know what concrete class the instance is at compile time, only that it implements staticMethod() somewhere along the inheritance chain.
EDIT: This answer is wrong. See comments for details.
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.
Has Java like other languages a directive to inline a method at compile time or at JIT time?
We have many methods that call only the super method. This make it clear that it was not forget to override the method.
For example you have override the equals methods but was use the same hashcode like super implementation. This make clear for a later developer that the hashcode method was not forget to implements. The same is also valid for setter and getter or add and remove.
But the compiler should inline this method.
The Java compiler does very few optimisations at compile time.
Instead the JIT does most of the optimisations at runtime based on how the applciation is actually used. It can inline methods, even up to two "virtual" methods.
No java does not. It's not a meaningful concept on Java.
As for the discussion of hashCode versus equals, some IDE and style checkers will warn you about mistakes like this, but I don't see that it has anything to do with 'inline'.
I don't think this can be inlined during compilation in Java, as all functions in Java are virtual, and you don't know until runtime which method is actually called, it might be the one of a subclass.
However, I don't think you need to worry about these things, because the HotSpot compiler should be pretty good at optimizing code that gets called frequently, on-the-fly, as the application is running.
Marking a method as final gives the JIT compiler a big hint as to how it can treat this method. You cannot force it to inline the method, but giving the JIT more explicit information can only help.