This question already has answers here:
What is inlining?
(10 answers)
Closed 9 years ago.
I've been trying to understand what that really means :
inline function
In C++, a member function defined in
the class declaration. (2) A function
call that the compiler replaces with
the actual code for the function. The
keyword inline can be used to hint to
the compiler to perform inline
expansion of the body of a member or
nonmember function.
inline
To replace a function call with a copy
of the function's code during
compilation.
For example it is written something like :
When a method is final, it may be
inlined.
Here : http://www.roseindia.net/javatutorials/final_methods.shtml
Can you give me an example or something or basically help me to understand what "it may be inlined" means.
Thanks.
Inlining is an optimization performed by the Java Just-In-Time compiler.
If you have a method:
public int addPlusOne(int a, int b) {
return a + b + 1;
}
which you call like this:
public void testAddPlusOne() {
int v1 = addPlusOne(2, 5);
int v2 = addPlusOne(7, 13);
// do something with v1, v2
}
the compiler may decide to replace your function call with the body of the function, so the result would effectively look like this:
public void testAddPlusOne() {
int v1 = 2 + 5 + 1;
int v2 = 7 + 13 + 1
// do something with v1, v2
}
The compiler does this to save the overhead of actually making a function call, which would involve pushing each parameter on to the stack.
This can clearly only be done for non-virtual functions. Consider what would happen if the method was overriden in a sub class and the type of the object containing the method isn't known until runtime...how would the compiler know what code to copy: the base class's method body or the sub class's method body? Since all methods are virtual by default in Java, you can explicitly mark those which cannot be overriden as final (or put them into a final class). This will help the compiler figure out that method will never be overriden, and it is safe to inline. (Note that the compiler can sometimes make this determination for non-final methods as well.)
Also, note the word may in the quote. Final methods aren't guaranteed to be inlineable. There are various ways you can guarantee a method isn't capable of being inlined, but no way to force the compiler to inline. It will almost always know better than you anyway when inlining will help vs. hurt the speed of the resulting code.
See wikipedia for a good overview of benefits and problems.
Let's say you have a class that looks like this:
public class Demo {
public void method() {
// call printMessage
printMessage();
}
public void printMessage() {
System.out.println("Hello World");
}
}
The call to printMessage could be "inlined" in the following way:
public class Demo {
public void method() {
// call printMessage
System.out.println("Hello World"); // <-- inlined
}
public void printMessage() {
System.out.println("Hello World");
}
}
(This is actually not done on the level of Java (not even on bytecode level) but during JIT-compilation, but the example above illustrates the concept of inlining.)
Now consider what would happen if the printMessage method was overloaded by another class, like this:
class SubDemo extends Demo {
public void printMessage() {
System.out.println("Something else");
}
}
Now if the compiler inlined the call to Demo.printMessage it would be stuck with System.out.println("Hello World"); which would be wrong in case the object was actually an instance of SubDemo.
However, if the method was declared final this would not under any circumstances be the case. If the method is "final" it means that it can never be overridden with a new definition, thus, it is safe to inline it!
Calling a function is not free. The machine must maintain a stack frame so that it can return to the calling section of code when the called function is complete. Maintaining the stack (including passing function parameters on this stack) takes time.
When a function is in-lined, the compiler replaces the call to the function with the function's code so that one can avoid the performance penalty of a function call at run-time. This is one of the classic trade-offs in programming: the run-time code gets a little bigger (takes up more memory), but it runs a little faster.
Related
I'm trying to accomplish passing a method in Java.
Here is the birds-eye-view of what I'm trying to do as a dummy example:
public final class A {
private String value;
public A(String value) {
this.value = value;
}
public final Object bind(Function<String, String> func) {
this.value = func.apply(value);
return this;
}
// Rest of the logic here to deal with `value`
}
public final class B {
public static void main(String[] args) {
A<T> a = new A("hello");
a.bind(B::methodOne).bind(B::methodTwo);
}
private String methodOne(String s) {
// method logic here
return "haha";
}
private String methodTwo(String s) {
// method logic here
return "hi";
}
}
So, basically, I've methods in a class, B in the above example, and I want to pass the methods of B to A and store the return value of that method of B on A for further processing.
I've tried to make use of method reference feature of Java but since I don't code daily with Java, I'm having a hard time getting my head around how to properly accomplish this while fulfilling the constraints above.
Currently, I'm getting a incompatible types: invalid method reference error while I do the binding in the main method.
Update
Made changes on my constraints of the program.
EDIT: The asker updated their question a lot after reading this answer. Crucially, originally each method had a completely different signature (different param types and amounts, and different return types). I'm leaving this answer untouched, be aware it is no longer particularly relevant to the question as it currently stands.
This doesn't work well because the methods you want to pass have completely different signatures (methodOne's is (B, String) -> int (why do you have a capital I Int in there, is that a typo?), methodTwo is (B) -> String, and methodThree is (B, String, String) -> String.
In java lambdas must fit a functional interface. It is not possible to have a functional interface for a variable number of input arguments.
With generics you can attempt to paper over the fact that the types of your inputs and output are different every time.
This really sounds like an X/Y problem: You have problem X (which you didn't explain and we don't know what it is), and you thought: I know! I'll use lambdas to abstract away the notion of 'a method'... and now you're asking questions about that.
But you're asking the wrong question. Ask X. Because even if hypothetically you could somehow fit your 3 methods all in the same lambda type (you can't), you would not then be able to invoke them.
Here's one more workable notion, but I have no idea if it solves your X because you didn't explain this:
#FunctionalInterface
public interface MyXThinger {
Object result(Object... args);
}
If you want to invoke this, how would you know that the particular MyXThinger (you didn't explain what X is, so I can't come up with a good name here) works if you pass 2 strings, and crashes if you pass anything else? That's.. more or less why I find your problem description insufficient to give solid advice here.
You're writing the expression B::methodOne in a static context.
non-static methods have an invisible parameter, called 'the receiver': It's the instance.
So, in a static context, B::methodOne has the signature: (B, String) -> String. What your bind method wants is (String) -> String, and these two are not compatible. Therefore, this does not work.
There are two ways to fix it:
create an instance: B b = new B(); a.bind(b::methodOne);. The expression b::methodOne, where b is a variable of type B referencing an actual instance of B (as created with new B()) DOES have the signature (String) -> String as required.
Make the methodOne method static, at which point it no longer has the invisible B instance parameter.
Your code is also littered with rookie mistakes; you must call a.bind and not A.bind, using A and B as class names is extremely confusing, your bind method returns Object (it should return A), etc. The way to fix those is to learn basic java, I think; trying to tackle those mistakes bit by bit seems unsuitable for what stackoverflow is for. Thus, I leave those as an exercise for you.
I created a class (class Special) whose method (Special.method()) will react differently depending on the method that calls Special.method(). so, lets say method X in some class calls Special.method(), if certain annotation is present in method X, the calc process invoked inside Special.method() will be different when such annotations didnt exist in the calling method. Also, since I'll be using third party library, it's not guaranteed that same thread will be used when calling Special.method() and method X.
I want to know ways to get reference to an instance method in Java 7
public class MyClass{
public void myMethod(){
....
}
}
I know I can do this
MyClass.class.getMethod(methodName);
but this technique is prone to error since it relies on String input (i.e. when method name is changed, etc). Is there a more reliable way to refer to a method?
Thanks
Java doesn't support method references without some fairly gnarly reflection. Java has functional interfaces that can work like references, but due to their targeted usage, they all take or return at least one value. There's no interface for methods which take no arguments and return void like you have in your example.
// Assignment context
Predicate<String> p = String::isEmpty;
Will declare a method reference to the String#isEmpty() method, which returns a boolean. That and similar interfaces exist in the java.lang.function package.
https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
Regarding your edit: If you want to find the caller of your method, see here:
How do I find the caller of a method using stacktrace or reflection?
The currently-accepted answer is incorrect: There is a functional interface compatible with your myMethod (e.g., accepting no parameters, with a void return type), it's just not in java.util.function, it's in java.lang: Runnable:
public class MyClass{
public void myMethod(){
System.out.println("myMethod was called");
}
}
class Example
{
public static void main (String[] args)
{
MyClass c = new MyClass();
Runnable r = c::myMethod; // <===
r.run(); // <===
}
}
Live on IDEOne
They just didn't duplicate it in java.util.function.
This question already has answers here:
Function with same name but different signature in derived class not found
(2 answers)
overloaded functions are hidden in derived class
(2 answers)
Closed 8 years ago.
I learned something new about C++ the other day; the following does not work:
class ParentClass {
public:
void someFunction() { printf("ParentClass::someFunction()"); }
};
class ChildClass : public ParentClass {
public:
void someFunction(int a) { printf("ChildClass::someFunction(int)"); }
};
int main() {
ChildClass childClass;
// This call is a compiler error.
// I would expect it to call ParentClass::someFunction()
childClass.someFunction();
}
However, doing exactly the same thing in Java (among other languages) works just as I would expect:
public class ParentClass {
public void someFunction() { System.out.println("ParentClass"); }
}
public class ChildClass extends ParentClass {
public void someFunction(int a) { System.out.println("ChildClass"); }
}
public class Main {
public static void main(String[] args) {
ChildClass childClass = new ChildClass();
// The following prints "ParentClass"
childClass.someFunction();
}
}
So what gives in C++? Why does this hide the name instead of overloading it?
If you're asking what the rules are, then name lookup stops as soon as it finds one or more overloads within one scope, and doesn't look at any wider scopes. So, in your case, the search for someFunction starts in the scope of ChildClass, finds a match, and stops.
Only the name is considered, not its usage (e.g. number of arguments in a function call), accessibility, or anything else. If none of the overloads are usable, the search still doesn't continue to other scopes, and the program is ill-formed.
If you're asking why the rules are like that, consider the case where, initially, there's just one function:
struct Base {};
struct Derived : Base {void f(int);}
and someone calls it with a type that doesn't quite match
Derived d;
d.f(42.0); // OK: double converts to int
Now suppose someone, who knows nothing about Derived, decides that Base could do with another function:
struct Base {
void f(double); // Completely unrelated to D::f
};
Under the C++ rules, that function will be ignored by the code using D::f, which will continue to work as before. If the new function were considered as an overload, it would be a better match, and the code using D::f would suddenly change behaviour, potentially leading to much head-scratching and lengthy debugging sessions.
If you want to include all the base-class functions in the scope of the derived class to be considered as overloads, then a using-declaration will do that. In your case:
using ParentClass::someFunction;
Alternatively, to avoid the situation described above at the cost of some tedious verbiage, you could write forwarding function(s) for the specific overload(s) you want:
void someFunction() {ParentClass::someFunction();}
In C++, name hiding can take place when one function in base class has the same name as one function in derived class. The reason is phases of the function call process.
In C++, phases of the function call process are as following
Name lookup
Overload resolution
Access control
Name lookup stops looking for other names as soon as it finds a name in derived class ChildClass. Therefore, ChildClass::someFunction() hides any function with name someFunction in ParentClass.
After the name lookup process, overload resolution fails since there is no someFunction() in ChildClass.
The core difference is that in C++ the method signature is essentially just the method name whereas in Java it is the method name and its parameters.
In your case, by using the same method name you are overriding the parent method so the parent method taking no parameters is not available any more. In Java you must override with a method that both has the same name and has the same parameters to override a method so in your case they are both still available.
There is a completely different debate about whether the return type should also be included - let's not go there.
Is calling super() constructor should be the very first line of the constructor? If so then why? Why can't I do some simple limited calculations before constructor call, for example, constructor parameters calculation?
I found a situation with inner class constructors which can be called with closure specification:
class A {
class Inner1 {
Inner1() {
// do something
}
}
}
class B {
A a1 = new A();
A a2 = new A();
class Inner2 extends A.Inner1 {
Inner2(boolean sel) {
(sel?a1:a2).super();
}
}
}
This case shows we can want to select enclosing instance for a base class constructor. Why selection logic should be so limited? Why one can't write something like this
if( sel ) {
a1.super();
}
else {
a2.super();
}
ADDITION
By my question I mean that the limitation could be like in the following case:
public class Base {
private final String content;
public Base(String content) {
this.content = content;
}
public String getContent() {
return content;
}
}
public class Derived extends Base {
public Derived(String content) {
super(String.format("Current value of content is %s.", getContent()));
}
}
In latter case I:
1) Fulfilling the requirement of super() to be in the first line
2) Violating the order of construction
3) Get a compiler error "Cannot refer to an instance method while explicitly invoking a constructor"
So, why we can't abolish "first line requirement" and rely only on errors like the last one?
Yes, a call to super() is required as the very first call in a constructor.
So much so that if you leave it out the compiler will (attempt to) insert the call for you. To understand the why, you would need to understand the philosophies of Java's designers. Gosling has always been in the camp of computer scientists that believe that accessing partially initialized objects is one of the bigger sources of bugs in computer programs. And as such he designed a strict initialization hierarchy that would help to alleviate this problem. Wether you agree with the philosophy is moot - but its important to realize that its as important a concept in Java as for example, references vs pointers, or real, bounded arrays. It should be noted that even languages like Objective C that allow you to invoke initialization at any time, go to great length to enforce initialization chaining, except that they need to do so via convention, as opposed to strict language rules.
I'm not sure what you were trying to illustrate in your example - but after years of development with Java I doubt you will find many cases where you really need to perform logic before invoking super.
Constructor calls are chained with super of every class in hierarchy being invoked before constructor of that class is invoked. As all classes in Java inherited from object class, so constructor of Object class is invoked first for every class with reason being that memory allocation for object is done by constructor of Object class
In a constructor in Java, if you want to call another constructor (or a super constructor), it has to be the first line in the constructor. I assume this is because you shouldn't be allowed to modify any instance variables before the other constructor runs. But why can't you have statements before the constructor delegation, in order to compute the complex value to the other function? I can't think of any good reason, and I have hit some real cases where I have written some ugly code to get around this limitation.
So I'm just wondering:
Is there a good reason for this limitation?
Are there any plans to allow this in future Java releases? (Or has Sun definitively said this is not going to happen?)
For an example of what I'm talking about, consider some code I wrote which I gave in this StackOverflow answer. In that code, I have a BigFraction class, which has a BigInteger numerator and a BigInteger denominator. The "canonical" constructor is the BigFraction(BigInteger numerator, BigInteger denominator) form. For all the other constructors, I just convert the input parameters to BigIntegers, and call the "canonical" constructor, because I don't want to duplicate all the work.
In some cases this is easy; for example, the constructor that takes two longs is trivial:
public BigFraction(long numerator, long denominator)
{
this(BigInteger.valueOf(numerator), BigInteger.valueOf(denominator));
}
But in other cases, it is more difficult. Consider the constructor which takes a BigDecimal:
public BigFraction(BigDecimal d)
{
this(d.scale() < 0 ? d.unscaledValue().multiply(BigInteger.TEN.pow(-d.scale())) : d.unscaledValue(),
d.scale() < 0 ? BigInteger.ONE : BigInteger.TEN.pow(d.scale()));
}
I find this pretty ugly, but it helps me avoid duplicating code. The following is what I'd like to do, but it is illegal in Java:
public BigFraction(BigDecimal d)
{
BigInteger numerator = null;
BigInteger denominator = null;
if(d.scale() < 0)
{
numerator = d.unscaledValue().multiply(BigInteger.TEN.pow(-d.scale()));
denominator = BigInteger.ONE;
}
else
{
numerator = d.unscaledValue();
denominator = BigInteger.TEN.pow(d.scale());
}
this(numerator, denominator);
}
Update
There have been good answers, but thus far, no answers have been provided that I'm completely satisfied with, but I don't care enough to start a bounty, so I'm answering my own question (mainly to get rid of that annoying "have you considered marking an accepted answer" message).
Workarounds that have been suggested are:
Static factory.
I've used the class in a lot of places, so that code would break if I suddenly got rid of the public constructors and went with valueOf() functions.
It feels like a workaround to a limitation. I wouldn't get any other benefits of a factory because this cannot be subclassed and because common values are not being cached/interned.
Private static "constructor helper" methods.
This leads to lots of code bloat.
The code gets ugly because in some cases I really need to compute both numerator and denominator at the same time, and I can't return multiple values unless I return a BigInteger[] or some kind of private inner class.
The main argument against this functionality is that the compiler would have to check that you didn't use any instance variables or methods before calling the superconstructor, because the object would be in an invalid state. I agree, but I think this would be an easier check than the one which makes sure all final instance variables are always initialized in every constructor, no matter what path through the code is taken. The other argument is that you simply can't execute code beforehand, but this is clearly false because the code to compute the parameters to the superconstructor is getting executed somewhere, so it must be allowed at a bytecode level.
Now, what I'd like to see, is some good reason why the compiler couldn't let me take this code:
public MyClass(String s) {
this(Integer.parseInt(s));
}
public MyClass(int i) {
this.i = i;
}
And rewrite it like this (the bytecode would be basically identical, I'd think):
public MyClass(String s) {
int tmp = Integer.parseInt(s);
this(tmp);
}
public MyClass(int i) {
this.i = i;
}
The only real difference I see between those two examples is that the "tmp" variable's scope allows it to be accessed after calling this(tmp) in the second example. So maybe a special syntax (similar to static{} blocks for class initialization) would need to be introduced:
public MyClass(String s) {
//"init{}" is a hypothetical syntax where there is no access to instance
//variables/methods, and which must end with a call to another constructor
//(using either "this(...)" or "super(...)")
init {
int tmp = Integer.parseInt(s);
this(tmp);
}
}
public MyClass(int i) {
this.i = i;
}
I think several of the answers here are wrong because they assume encapsulation is somehow broken when calling super() after invoking some code. The fact is that the super can actually break encapsulation itself, because Java allows overriding methods in the constructor.
Consider these classes:
class A {
protected int i;
public void print() { System.out.println("Hello"); }
public A() { i = 13; print(); }
}
class B extends A {
private String msg;
public void print() { System.out.println(msg); }
public B(String msg) { super(); this.msg = msg; }
}
If you do
new B("Wubba lubba dub dub");
the message printed out is "null". That's because the constructor from A is accessing the uninitialized field from B. So frankly it seems that if someone wanted to do this:
class C extends A {
public C() {
System.out.println(i); // i not yet initialized
super();
}
}
Then that's just as much their problem as if they make class B above. In both cases the programmer has to know how the variables are accessed during construction. And given that you can call super() or this() with all kinds of expressions in the parameter list, it seems like an artificial restriction that you can't compute any expressions before calling the other constructor. Not to mention that the restriction applies to both super() and this() when presumably you know how to not break your own encapsulation when calling this().
My verdict: This feature is a bug in the compiler, perhaps originally motivated by a good reason, but in its current form it is an artifical limitation with no purpose.
I find this pretty ugly, but it helps
me avoid duplicating code. The
following is what I'd like to do, but
it is illegal in Java ...
You could also work around this limitation by using a static factory method that returns a new object:
public static BigFraction valueOf(BigDecimal d)
{
// computate numerator and denominator from d
return new BigFraction(numerator, denominator);
}
Alternatively, you could cheat by calling a private static method to do the computations for your constructor:
public BigFraction(BigDecimal d)
{
this(computeNumerator(d), computeDenominator(d));
}
private static BigInteger computeNumerator(BigDecimal d) { ... }
private static BigInteger computeDenominator(BigDecimal d) { ... }
The constructors must be called in order, from the root parent class to the most derived class. You can't execute any code beforehand in the derived constructor because before the parent constructor is called, the stack frame for the derived constructor hasn't even been allocated yet, because the derived constructor hasn't started executing. Admittedly, the syntax for Java doesn't make this fact clear.
Edit: To summarize, when a derived class constructor is "executing" before the this() call, the following points apply.
Member variables can't be touched, because they are invalid before base
classes are constructed.
Arguments are read-only, because the stack frame has not been allocated.
Local variables cannot be accessed, because the stack frame has not been allocated.
You can gain access to arguments and local variables if you allocated the constructors' stack frames in reverse order, from derived classes to base classes, but this would require all frames to be active at the same time, wasting memory for every object construction to allow for the rare case of code that wants to touch local variables before base classes are constructed.
"My guess is that, until a constructor has been called for every level of the heierarchy, the object is in an invalid state. It is unsafe for the JVM to run anything on it until it has been completely constructed."
Actually, it is possible to construct objects in Java without calling every constructor in the hierarchy, although not with the new keyword.
For example, when Java's serialization constructs an object during deserialization, it calls the constructor of the first non-serializable class in the hierarchy. So when java.util.HashMap is deserialized, first a java.util.HashMap instance is allocated and then the constructor of its first non-serializable superclass java.util.AbstractMap is called (which in turn calls java.lang.Object's constructor).
You can also use the Objenesis library to instantiate objects without calling the constructor.
Or if you are so inclined, you can generate the bytecode yourself (with ASM or similar). At the bytecode level, new Foo() compiles to two instructions:
NEW Foo
INVOKESPECIAL Foo.<init> ()V
If you want to avoid calling the constructor of Foo, you can change the second command, for example:
NEW Foo
INVOKESPECIAL java/lang/Object.<init> ()V
But even then, the constructor of Foo must contain a call to its superclass. Otherwise the JVM's class loader will throw an exception when loading the class, complaining that there is no call to super().
Allowing code to not call the super constructor first breaks encapsulation - the idea that you can write code and be able to prove that no matter what someone else does - extend it, invoke it, instansiate it - it will always be in a valid state.
IOW: it's not a JVM requirement as such, but a Comp Sci requirement. And an important one.
To solve your problem, incidentally, you make use of private static methods - they don't depend on any instance:
public BigFraction(BigDecimal d)
{
this(appropriateInitializationNumeratorFor(d),
appropriateInitializationDenominatorFor(d));
}
private static appropriateInitializationNumeratorFor(BigDecimal d)
{
if(d.scale() < 0)
{
return d.unscaledValue().multiply(BigInteger.TEN.pow(-d.scale()));
}
else
{
return d.unscaledValue();
}
}
If you don't like having separate methods (a lot of common logic you only want to execute once, for instance), have one method that returns a private little static inner class which is used to invoke a private constructor.
My guess is that, until a constructor has been called for every level of the heierarchy, the object is in an invalid state. It is unsafe for the JVM to run anything on it until it has been completely constructed.
Well, the problem is java cannot detect what 'statements' you are going to put before the super call. For example, you could refer to member variables which are not yet initialized. So I don't think java will ever support this.
Now, there are many ways to work around this problem such as by using factory or template methods.
Look it this way.
Let's say that an object is composed of 10 parts.
1,2,3,4,5,6,7,8,9,10
Ok?
From 1 to 9 are in the super class, part #10 is your addition.
Simple cannot add the 10th part until the previous 9 are completed.
That's it.
If from 1-6 are from another super class that fine, the thing is one single object is created in a specific sequence, that's the way is was designed.
Of course real reason is far more complex than this, but I think this would pretty much answers the question.
As for the alternatives, I think there are plenty already posted here.