Refactorings
Description: Change the name of a program symbol
Example:
Before refactoring:
for(int a=0; a<args.length; a++) {
action(args[a]);
}
After refactoring:
for(int i=0; i<args.length; i++) {
action(args[i]);
}
Refactoring Context: Cursor has to be on the symbol.
Input parameters: New name of the symbol (for example: 'i')
Mechanics: Replace old symbol name by the new name on all its
occurences in the project. In case of public class stored in a
file of the same name, also rename the file. In case of
package also store files in new directories.
Description: Add parameter to a method, function or macro.
Example:
Before refactoring:
public int method(int x) {
if (x<=1) return(1);
return(method(x-1)+method(x-2));
}
After refactoring:
public int method(int x, int y) {
if (x<=1) return(1);
return(method(x-1, 0)+method(x-2, 0));
}
Refactoring Context: Cursor has to be on the method's (function's or
macro's) name.
Input parameters: Position of the new parameter, its declaration and
default value. (for example: '2', 'int y' and '0').
Mechanics: Inspect all references of the method (function or macro)
and add declaration of the new parameter to each definition
and default value to each invocation of the method.
Description: Delete parameter of a method, function or macro.
Example:
Before refactoring:
public int method(int x, int y) {
if (x<=1) return(1);
return(method(x-1, 0)+method(x-2, 0));
}
After refactoring:
public int method(int x) {
if (x<=1) return(1);
return(method(x-1)+method(x-2));
}
Refactoring Context: Cursor has to be on the method's (function's or
macro's) name.
Input parameters: Position of the parameter to delete (for example:
'2').
Mechanics: Inspect all references of the method (function or macro)
and remove the parameter.
Description: Reorder parameter of a method, function or macro.
Example:
Before refactoring:
public int method(int x, int y) {
if (x<=1) return(1);
return(method(x-1, 0)+method(x-2, 0));
}
After refactoring:
public int method(int y, int x) {
if (x<=1) return(1);
return(method(0, x-1)+method(0, x-2));
}
Refactoring Context: Cursor has to be on the method's (function's or
macro's) name.
Input parameters: Old and new positions of the parameter (for example:
'1' and '2').
Mechanics: Inspect all references of the mehod and move the parameter
from its original to its new position.
Description: Extract region into new method (function or macro).
Example:
Before refactoring:
public static void main(String[] args) {
int i,n,x,y,t;
n = Integer.parseInt(args[0]);
x=0; y=1;
for(i=0; i<n; i++) {
t=x+y; x=y; y=t;
}
System.out.println("" + n + "-th fib == " + x);
}
After refactoring:
static int fib(int n) {
int i, x, y, t;
x=0; y=1;
for(i=0; i<n; i++) {
t=x+y; x=y; y=t;
}
return(x);
}
public static void main(String[] args) {
int i,n,x,y,t;
n = Integer.parseInt(args[0]);
x = fib(n);
System.out.println("" + n + "-th fib == " + x);
}
Refactoring Context: The code for extraction has to be selected within
the editor.
Input Parameters: Name fo the new method (function or macro).
Mechanics: Copy the region before the method (function), generate new
header and footer based on static analysis of code and
generate call to the new method at the original place.
Description: Expand types to fully qualified names
Example:
Before refactoring:
package com.xrefactory.refactorings;
import javax.swing.*;
class Hello {
public static void main(String argv[]) {
JOptionPane.showMessageDialog(null, "Hello world");
}
}
After refactoring:
package com.xrefactory.refactorings;
import javax.swing.*;
class Hello {
public static void main(java.lang.String argv[]) {
javax.swing.JOptionPane.showMessageDialog(null, "Hello world");
}
}
Refactoring Context: Cursor has to be on a definition of a class.
Input Parameters: None.
Mechanics: Replace short type names by fully qualified names.
Description: Reduce fully qualified type names to short form.
Example:
Before refactoring:
package com.xrefactory.refactorings;
class Hello {
public static void main(java.lang.String argv[]) {
javax.swing.JOptionPane.showMessageDialog(null, "Hello world");
}
}
After refactoring:
package com.xrefactory.refactorings;
import javax.swing.JOptionPane;
class Hello {
public static void main(String argv[]) {
JOptionPane.showMessageDialog(null, "Hello world");
}
}
Refactoring Context: Cursor has to be on a definition of a class.
Input Parameters: None.
Mechanics: Replace fully qualified names by short names. If the type
is not imported then add either import on demand or single
type import command.
Description: Set target positon for moving refactorings
Refactoring Context: Cursor has to be on the position where the field,
method or class will be moved, pulled up or pushed down.
Input Parameters: None.
Description: Move static field or method to another place.
Example:
Before refactoring:
class Target {
static int i=0;
}
class Source {
static int j=1;
public static void method() {
System.out.println("i, j == " + Target.i + ", " + j);
}
public static void main(String[] args) {
method();
}
}
After refactoring:
class Target {
static int i=0;
public static void method() {
System.out.println("i, j == " + i + ", " + Source.j);
}
}
class Source {
static int j=1;
public static void main(String[] args) {
Target.method();
}
}
Refactoring Context: Target place has to set using 'Set Target
Position', cursor has to be on the name of the method
(field) to be moved (at its definition).
Input Parameters: None.
Mechanics: Move the method (field), adjust all references within its
body (initialisation) and all its references in the
project.
Description: Move class from one place to another.
Example:
Before refactoring:
class A {
static int i;
static class B {
static void method() {
System.out.println("i==" + i);
}
}
}
After refactoring:
class A {
static int i;
}
class B {
static void method() {
System.out.println("i==" + A.i);
}
}
Refactoring Context: Target place has to set using 'Set Target
Position', cursor has to be on the name of the class to be
moved (at its definition).
Input Parameters: None.
Mechanics: Move the class and adjust all its references.
Description: Move class into its own file.
Example:
Before refactoring:
---- file A.java
package pack;
class A {
static int i;
static class B {
static void method() {
System.out.println("i==" + i);
}
}
}
After refactoring:
---- file A.java
package pack;
class A {
static int i;
}
---- file B.java
package pack;
public class B {
static void method() {
System.out.println("i==" + A.i);
}
}
Refactoring Context: Cursor has to be on the name of the class to be
moved (at its definition).
Input Parameters: Name of the file to create
Mechanics: Create new file, add package and imports and move the class
and adjust all its references.
Description: Move field from one class to another
Example:
Before refactoring:
class Target {
}
class Source {
Target link;
int field;
public int method() {
return(field);
}
}
After refactoring:
class Target {
int field;
}
class Source {
Target link;
public int method() {
return(link.field);
}
}
Refactoring Context: Target place has to set using 'Set Target
Position', cursor has to be on the name of the field to be
moved (at its definition).
Input Parameters: the field pointing from source class to target class
(in the example: 'link').
Mechanics: Move the field, inspect all its references add insert the
field pointing from source to target.
Comment: This refactoring relies on semantic properties of the
program, it can not be ensured to be 100% safe by static
analysis of the program.
Description: Move method (field) up (down) in the class hierarchy.
Example:
Before refactoring:
class SuperClass {
int x = 0;
int y = 0;
}
class InferClass extends SuperClass {
int y = 1;
void method() {
System.out.println("x == " + x);
System.out.println("this.x == " + this.x);
System.out.println("this.y == " + this.y);
System.out.println("super.y == " + super.y);
}
public static void main(String args[]) {
(new InferClass()).method();
}
}
After refactoring:
class SuperClass {
int x = 0;
int y = 0;
public void method() {
System.out.println("x == " + x);
System.out.println("this.x == " + this.x);
System.out.println("this.y == " + ((InferClass)this).y);
System.out.println("super.y == " + this.y);
}
}
class InferClass extends SuperClass {
int y = 1;
public static void main(String args[]) {
(new InferClass()).method();
}
}
Refactoring Context: Target place has to set using 'Set Target
Position', cursor has to be on the name of the method
(field) to be moved (at its definition).
Input Parameters: None.
Mechanics: Move the method and adjust references inside its body
(initialisation).
Description: Generate field accessors and their invocations.
Example:
Before refactoring:
class EncapsulateField {
public int field;
void incrementField() {
field = field + 1;
}
}
class AnotherClass extends EncapsulateField {
void printField() {
System.out.println("field == " + field);
}
}
After refactoring:
class EncapsulateField {
private int field;
public int getField() {return field;}
public int setField(int field) { this.field=field; return field;}
void incrementField() {
setField(getField() + 1);
}
}
class AnotherClass extends EncapsulateField {
void printField() {
System.out.println("field == " + getField());
}
}
Refactoring Context: Cursor has to on the name of the field to
encapsulate (on its definition).
Input Parameters: None.
Mechanics: Generate getter and setter methods. Inspect all references
of the field and replace them by appropriate accessor. The
Self Encapsulate field (in difference to Encapsulate field)
processes also references within the class defining the
field (see example). The Encapsulate Field will left those
references untouched.
Description: Turn method into static.
Example:
Before refactoring:
class Project {
Person[] participants;
}
class Person {
int id;
public boolean participate(Project proj) {
for(int i=0; i<proj.participants.length; i++) {
if (proj.participants[i].id == id) return(true);
}
return(false);
}
}
After refactoring:
class Project {
Person[] participants;
static public boolean participate(Person person, Project proj) {
for(int i=0; i<proj.participants.length; i++) {
if (proj.participants[i].id == person.id) return(true);
}
return(false);
}
}
class Person {
int id;
}
Refactoring Context: Cursor has to on the name of the method to be
turned static (on its name).
Input Parameters: The name of the new parameter (in the example:
'person').
Mechanics: Add new parameter to the method passing its invocation
object. Make all accesses to method's object via the new
parameter. Declare the method static and make all method
invocations static.
Comment: This refactoring is usualy used to move virtual method from
one class to another in the sequence 'Turn Virtual Method
into Static', 'Move Static Method' and 'Turn Static Method
into Virtual'.
Description: Make the method virtual.
Example:
Before refactoring:
class Target {
int field;
static int method(Source ss) {
System.out.println("field==" + ss.link.field);
}
}
class Source {
Target link;
static void main(String[] args) {
Target.method(new Source());
}
}
After refactoring:
class Target {
int field;
int method() {
System.out.println("field==" + field);
}
}
class Source {
Target link;
static void main(String[] args) {
new Source().link.method();
}
}
Refactoring Context: Cursor has to on the name of the method to be
turned virtual (on its name).
Input Parameters: The parameter containing method's object. Optionally
a field getting method's object from the parameter. In the
example: '1' and "link".
Mechanics: Remove the 'static' keyword, inspect all references and
apply method on the method's object (method's object is
determine from the combination of parameter and field).
Comment: This refactoring is usualy used to move virtual method from
one class to another in the sequence 'Turn Virtual Method
into Static', 'Move Static Method' and 'Turn Static Method
into Virtual'.