I've been using the Intellij Idea constructor generator as per https://www.jetbrains.com/help/idea/generating-constructors.html and it's been working fine except for the location of generated constructors.
"The generated constructors are inserted at the points defined in the Order of Members section of the Code Style settings. By default, the code generator places constructors after the fields."
The Code Style settings doesn't have anything about Order of Members that I can find, and the code generator seems to be just putting constructors wherever the cursor happens to be at the time.
How do you get the code generator to put them in the right place?
If the cursor is located in a position where IntelliJ can validly insert a constructor then IntelliJ will insert the generated constructor in that position.
If the cursor is not located in a position where IntelliJ can validly insert a constructor then IntelliJ will insert the generated constructor according to the "Order of Members".
To verify this ...
Place your cursor on the class name and then invoke the constructor generator (Code > Generate ... > Constructor) and the generated constructor will be inserted according to "Order of Members"; typically after member declarations and any other constructors already present in the class.
Place your cursor on an empty line within the class and then invoke the constructor generator (Code > Generate ... > Constructor) and the generated constructor will be inserted at your cursor location.
Have you looked under Settings -> Editor -> Code Style -> Java? There, you'll find an "Arrangement" tab that lets you define the order of fields, methods and constructors:
Related
SomeClass {
AbstractType/Interface instanceVariable = new SpecificType();
...
SomeFn(){
instanceVariable.instanceMethod();
| <- go to SpecificType.instanceMethod() directly
instanceVariable.instanceMethod();
| < go to SpecificType of instanceVariable directly
}
Looking for an Intellij shortcut to go to variable's Specific Class. To go to instanceVariable in a large code and want to go to its SpecificType class. It needs three commands, go to instanceVariable definition using Go to Declaration (F3), see its definition, move cursor to actual type new SpecificType();, go into it and come back where you were using (Command + [). We can also hover over "instanceVariable" definition using F2 to see what its type is, but, there is no direct shortcut to go to actual Class "SpecificType" defining this instance variable.
Same with instanceMethod(), there is "Go to Implementation" on this method of an instance (Shift+Command+I) and choose specific type whereas instance is already defined right in the class as "SpecificType" here. See method type using F2 to see which class, in this case, it will show "SpecificType" the method type belongs to, then choose the specific implementation and choose SpecificType from several drop downs.
It would be nice if there was a shortcut to directly to to exact SpecificType Class or its method instead of multiple commands.
Why Main Menu | Navigate | Go to Implementation(s) action (Alt+Cmd+B default shortcut) doesn't work for you? Invoke it on the method call and from drop-down choose the implementation you are interested in:
Inside a method of some class, I typed a field name that doesn't exist yet. I invoked the Generate > Field command. IDEA generated the field but placed it somewhere far up the class - probably at a position determined by Code Style > Arrangement.
Is there a way to configure IDEA to place newly generated code as close to the cursor as possible? E.g., in the example above I wanted the new field to be placed right above my method.
While modifying an existing program's CASE statement, I had to add a second block where some logic is repeated to set NetWeaver portal settings. This is done by setting values in a local variable, then assigning that variable to a Changing parameter. I copied over the code and did a Pretty Print, expecting to compiler to complain about the unknown variable. To my surprise however, this code actually compiles just fine:
CASE i_actionid.
WHEN 'DOMIGO'.
DATA: ls_portal_actions TYPE powl_follow_up_sty.
CLEAR ls_portal_actions.
ls_portal_actions-bo_system = 'SAP_ECC_Common'.
" [...]
c_portal_actions = ls_portal_actions.
WHEN 'EBELN'.
ls_portal_actions-bo_system = 'SAP_ECC_Common'.
" [...]
C_PORTAL_ACTIONS = ls_portal_actions.
ENDCASE.
As I have seen in every other programming language, the DATA: declaration in the first WHEN statement should be encapsulated and available only inside that switch block. Does SAP ignore this encapsulation to make that value available in the entire CASE statement? Is this documented anywhere?
Note that this code compiles just fine and double-clicking the local variable in the second switch takes me to the data declaration in the first. I have however not been able to test that this code executes properly as our testing environment is down.
In short you cannot do this. You will have the following scopes in an abap program within which to declare variables (from local to global):
Form routine: all variables between FORM and ENDFORM
Method: all variables between METHOD and ENDMETHOD
Class - all variables between CLASS and ENDCLASS but only in the CLASS DEFINITION section
Function module: all variables between FUNCTION and ENDFUNCTION
Program/global - anything not in one of the above is global in the current program including variables in PBO and PAI modules
Having the ability to define variables locally in a for loop or if is really useful but unfortunately not possible in ABAP. The closest you will come to publicly available documentation on this is on help.sap.com: Local Data in the Subroutine
As for the compile process do not assume that ABAP will optimize out any variables you do not use it won't, use the code inspector to find and remove them yourself. Since ABAP works the way it does I personally define all my variables at the start of a modularization unit and not inline with other code and have gone so far as to modify the pretty printer to move any inline definitions to the top of the current scope.
Your assumption that a CASE statement defines its own scope of variables in ABAP is simply wrong (and would be wrong for a number of other programming languages as well). It's a bad idea to litter your code with variable declarations because that makes it awfully hard to read and to maintain, but it is possible. The DATA statements - as well as many other declarative statements - are only evaluated at compile time and are completely ignored at runtime. You can find more information about the scopes in the online documentation.
The inline variable declarations are now possible with the newest version of SAP Netweaver. Here is the link to the documentation DATA - inline declaration. Here are also some guidelines of a good and bad usage of this new feature
Here is a quote from this site:
A declaration expression with the declaration operator DATA declares a variable var used as an operand in the current writer position. The declared variable is visible statically in the program from DATA(var) and is valid in the current context. The declaration is made when the program is compiled, regardless of whether the statement is actually executed.
Personally have not had time to check it out yet, because of lack of access to such system.
If my class has a non-empty constructor, is it possible to auto-complete parameters in the new expression?
With Eclipse, if you press ctrl+space when the cursor is between the parenthesis:
MyClass myObject = new MyClass();
it will find the appropriate parameters.
--> MyClass myObject = new MyClass(name, value);
When I use ctrl+shift+spacebar after the new, Intellij shows me the constructors, but I can't choose one for auto-completion. Am I missing an option?
I usually start with CtrlP (Parameter Info action) to see what arguments are accepted (auto guess complete is way to error prone in my opinion). And if as in your case you want to fill in name type n a dropdown menu appears with all available variables/fields (etc) starting with n Arrow Up/Down and Tab to select name, or CtrlSpace to select a method (or even CtrlAltSpace to be killed by suggestions;-), followed by , and v Tab for value.
Well I used the eclipse key map where Parameter Info is unassigned.
Here is how to change that:
Well there's the Ctrl+Shift+Space combination, which tries to come up with a set of possible arguments. And if you press the Ctrl+Shift+Space a second time, Idea tries find arguments which fit across multiple calls & conversions.
So in your example Ctrl+Shift+Space would almost certainly bring up the 'name' as suggestion. And the next Ctrl+Shift+Space would bring up 'value' as suggestion.
In Intellij Idea 2016.3 you can use option + return. It will ask you if you want to introduce the named argument for the argument you are on and all the followers.
There's no such possibility yet. As IDEA doesn't fill the arguments automatically, distinguishing the constructors in the lookup makes no sense. There's a request for that (http://youtrack.jetbrains.net/issue/IDEABKL-5496) although I sincerely believe such a behavior is too dangerous and error-prone.
There is a "NameAndType" structure in the constants pool in .class file.
It is used for dynamic binding.
All methods that class can "export" described as "signature + return type".
Like
"getVector()Ljava/util/Vector;"
That breakes my code when return type of the method in some .jar is changed, even if new type is narrower.
i.e:
I have the following code:
List l = some.getList();
External .jar contains:
public List getList()
Than external jar changes method signature to
public ArrayList getList().
And my code dies in run-time with NoSuchMethodException, because it can't find
getList()Ljava/util/List;
So, I have to recompile my code.
I do not have to change it. Just recompile absolutely the same code!
That also gives ability to have two methods with one signature, but different return types! Compiler would not accept it, but it is possible to do it via direct opcoding.
My questions is why?
Why they did it?
I have only one idea: to prevent sophisticated type checking in the runtime.
You need to look up to the hierarchy and check if there is a parent with List interface.
It takes time, and only compiler has it. JVM does not.
Am I right?
thanks.
One reason may be because method overloading (as opposed to overriding) is determined at compile time. Consider the following methods:
public void doSomething(List util) {}
public void doSomething(ArrayList util) {}
And consider code:
doSomething(getList());
If Java allowed the return type to change and did not throw an exception, the method called would still be doSomething(List) until you recompiled - then it would be doSomething(ArrayList). Which would mean that working code would change behavior just for having recompiled it.