Java Coding Conventions

De la WikiLabs
Jump to navigationJump to search

During the OOP lab you will also get points for the way the source code is paged and tabbed, for the naming of classes, methods and variables, and for the general structure of the program. The conventions that need to be followed are:

  • avoid the use of inner-classes, so a Java file has only one class defined;
  • the segments of the file should appear in the following order:
    • header comment (optional), describing the role of the class, the author, and the project it is part of;
    • package definition, if it exists;
    • import directives;
    • the class or interface declaration;
    • field declarations, all indented with one tab, in the following order:
      • class constants;
      • static fields;
      • instance fields;
    • static methods;
    • constructors, starting from the least complex to the most complex;
    • methods;
    • footer comment (optional), describing the changes in the file;
  • the segments of the file are separated by an empty line or a comment-line;
  • field declarations may have no empty line between them;
  • succesive methods and constructors are separated for clarity by an empty line or a comment-line;
  • the main method, if it exists, is placed immediately before the first constructor;
  • for the block of statements attached to an if / else / do-while / for / case and for the body of a class / method, the open curly bracket is placed on the same line with the if / else / do / for / case keyword, respectively the class / method declaration, and the closed curly bracket is placed on a separate line, on the same column with the first letter of the keyword / declaration;
  • an instruction block is indented by one extra tab in respect to the previous level;
  • class names (and therefore the constructor names) start with an uppercase letter;
  • method names start with a lowercase letter;
  • field names start with a lowercase letter;
  • constant names are written in caps, words separated by the "_" character;
  • method arguments and local variables start with a lowercase letter;
  • the naming must be as explicit as possible regarding their purpose, in order to avoid excessive comments. The only exceptions are the for / do-while loop counters, which may be single letter words, like i, j, k, etc.
  • it is allowed to insert blank lines, if a natural segregation of elements is obtained through it;
  • any source file ends with a new line;
  • the access modifier (if used) is always the first modifier for a class / method / field declaration;
  • the static modifier, if present, comes before the final modifier;
  • for indentation use exactly 4 blank spaces. Avoid the use of tabs or make sure that tabs are translated into exactly four white spaces.
  • all local variables declarations are put at the beginning of their scope (at the beginning of the block inside which they are declared);

These coding conventions are a necessary minimum for the OOP lab. For those who wish to study the coding conventions recommended by Oracle, they can find it online.

Example (attention, this program will not function on its own since it is part of a project:

//------------------------------------------------------------------------------
//
//		This is the title of the Project
//			- Assembler -
//
//------------------------------------------------------------------------------
//
//  The role of this class is to provide an example as to how a Java
// class is structured and how the code is written. It provides examples
// for naming conventions and code alignment.
//
//------------------------------------------------------------------------------
package ro.pub.arh.beam.assembler;

//------------------------------------------------------------------------------
import ro.pub.arh.beam.assembler.structs.*;
import java.io.*;
import java.util.Vector;
import ro.pub.arh.beam.structs.*;
import ubiCORE.jroot.common.utils.ErrorCode;
import ro.pub.arh.beam.common.HexConverter;
//------------------------------------------------------------------------------
public class Assembler{

    public static final int REGISTER_COUNT = 32;
    public static final String INSTRUCTION_SEPARATOR = "\\|";
    public static final String OPERAND_SEPARATOR = "\\s+|\\s*\\,\\s*";
    
    private static PrintStream dumpStream = System.out;

    private String fileName;

    private int currentAddress;
    private int currentLine;

    private Program program;
    private Function function;
    private int entityIndex;

//------------------------------------------------------------------------------
public static void main(String[] _args){
    try{
        new Assembler(_args[0]).run();
    }catch(ArrayIndexOutOfBoundsException _aiobe){
        out("File is empty or no file specified.");
    }catch(Exception _e){
        _e.printStackTrace();
        out("Assembly error: " + _e.getMessage());
    }
}

//------------------------------------------------------------------------------
public Assembler(String _fileName){
    fileName = _fileName;
    currentAddress = 0;
    currentLine = 1;
}

//------------------------------------------------------------------------------
public void run() throws IOException, ErrorCode{

    BufferedReader _reader = new BufferedReader(new FileReader(fileName));
    String _line;
    Vector<Instruction> _instructions = null;
    boolean _atLeastOneError = false;

    entityIndex = 0;
    program = new Program(fileName);
    do{
        _line = _reader.readLine();
        if(_line == null){
            program.add(function);
            break;
        }
        _line = trimWhiteSpaces(_line);
        try{
            _instructions = null;
            _instructions = processLine(_line);

            if(_instructions != null){
                function.addAll(_instructions);
                currentAddress += Instruction.INSTRUCTION_LOCATION_COUNT;
            }
        }catch(RuntimeException _re){
            out("Line " + currentLine + ": " + _re.getMessage());
            //_re.printStackTrace();
            _atLeastOneError = true;
        }
        
        currentLine++;
    }while(true);

    if(_atLeastOneError){
        out("Finished with errors.");
        throw new RuntimeException("Assembly failed.");
    }
    
    out("No syntax errors.");
    //placeIRQHandler("irq_handler", MachineConstants.IRQ_HANDLER_ADDR);
    replaceJumpLabels();
    buildLineSeeker();

    out("Assembly succesfull!");

    program.sort();

}

//------------------------------------------------------------------------------
private Vector<Instruction> processLine(String _line){
//...
}

//------------------------------------------------------------------------------
private String trimWhiteSpaces(String _line){
    _line = _line.substring(0, _line.indexOf("//") == -1 ? _line.length() : _line.indexOf("//"));
    _line = _line.substring(0, _line.indexOf(";") == -1 ? _line.length() : _line.indexOf(";"));
    _line = _line.trim();
    _line = _line.replaceAll("\\s+", " ");
    return _line;
}

//------------------------------------------------------------------------------
private int getValueOfString(String _number){
    int _value;

    try{
        if(_number.startsWith("0x")){
            _value = Integer.parseInt(_number.substring(2), 16);
        }else{
            _value = Integer.parseInt(_number);
        }
    }catch(NumberFormatException _nfe){
        throw new RuntimeException("Invalid new code address");
    }

    if(_value % 4 != 0){
        throw new RuntimeException("Invalid new code address " + currentLine + ". Address must divide by 4.");
    }
    return _value;
}

//------------------------------------------------------------------------------
private void replaceJumpLabels(){
    int _address = 0;
    Instruction _instruction = null;

    for(int i=0; i<program.size(); i++){
        Function _function = program.elementAt(i);
        for(int j=0; j<program.elementAt(i).size(); j++){
            _instruction = _function.elementAt(j);
            if(_instruction.getLabel() != null){
                String _label = extractLabel(_instruction.getLabel());
                if(_instruction.isCall()){
                    _address = program.findAddressOfFunction(_label);
                }else if(_instruction.isAbsoluteJump()){
                    _address = program.findAddressOfLabel(_label);
                }else{
                    _address = program.findAddressOfLabel(_label) - _instruction.getAddress();
                }

                _instruction.setLabelAddress(offsetAddress(_address, _instruction.getLabel()));
            }
        }
    }
}

//------------------------------------------------------------------------------
}
//------------------------------------------------------------------------------
//      Change History:
//      $Log: Assembler.java,java First file revision.$