Java Programming Guidelines

  1. Objetivo
  2. Escopo de Aplicação
  3. Descrição Sumária
  4. Acrônimos
  5. Papéis / Áreas Funcionais e Responsabilidades
  6. Instruções Operacionais
    1. Prefácio
    2. Introdução
    3. Objetivos dessas definições e regras
    4. Quem deve ler esse documento
    5. Pré-requisitos
    6. Estrutura do Documento
  7. Nome de Arquivo e Convenções da Estrutura
    1. Nome de arquivo
      1. Regra -Todos os arquivos fontes devem ter a extensão .java
      2. Regra -Todas as classes Java devem conter a extensão .class
      3. Regra -Nome do Package deve servir como mapa para o nome dos arquivos Java
      4. Definição -Criação de packages para a organização de classes
    2. Estrutura dos arquivos
      1. Definição -Gerenciando referencias em ciclos
      2. Definição -Numero de classes por arquivo
      3. Regra -Especificar os tipos de import
      4. Regra -Tamanho dos métodos
      5. Regra -Não declare múltiplas variáveis de tipos diferentes em um único statement
      6. Regra -Evitar assinatura de métodos com muitos parâmetros
      7. Definição -Escreva um statement por linha
  8. Documentação
    1. Arquivo e descrições
      1. Regra -Use uma tag padrão para indicar mudança
      2. Regra -Use prefácios para padronização de classes, métodos e campos
      3. Regra -Um projeto deve adotar um estilo de comentário consistente
      4. Descrição -Alinhar elementos de definição de classes/interface
    2. Estrutura de controle
      1. Regra -Não use operador ternário dentro de outras funções.
      2. Regra -Todos os switch statements devem conter um default case
      3. Regra -Uso explicito de comparação dentro de testes condicionais
      4. Regra -Estruturas de controle aninhadas
      5. Definição -Adotar um consistente estilo de endentação e abertura e fechamento de blocos de controle
      6. Definição -Termine cada bloco case com um statement break
      7. Definição -Overflows/underflows sobre sinais aritméticos
      8. Regra -Coloque constantes no lado esquerdo das comparações
      9. Regra -Declare 'for' loops com uma condição e statement de incremento
      10. Regra -Evitar atribuições dentro de uma condição if
      11. Regra -Evitar statements 'for' com corpo vazio
      12. Regra -Não atribua valor a variáveis de controle dentro do corpo de um 'for' loop
      13. Regra -Evitar statements 'if' com corpo vazio
    3. Convenção para identificação de nome
      1. Regra -Convenção de nomes para os elementos de um programa
      2. Definição -Não redefinir um identificador que já tenha sido declarado em um mesmo delimitador de escopo
      3. Definição -Variáveis de loop devem ser identificadas como i, j, k, ...
      4. Definição -Explicitar o tempo de vida de uma variável de controle
    4. Convenção de nomes para classes e interface
      1. Regra -Todos os nomes devem começar com letra maiúscula
    5. Convenção de nomes de campos
      1. Definição -Definindo array de um determinado tipo
      2. Use "L" ao invés de "l" para expressar constantes do tipo long
    6. Convenções para nome de métodos
      1. Regra -Todos os nomes de métodos devem começar com letras minúsculas
      2. Regra -Não inclua o nome do tipo no nome do método
      3. Regra -Use static final na declaração de constantes
      4. Definição -Use prefixos comuns e consistente para métodos
      5. Descrição -Use nomes descritivos para os parâmetros dos métodos
  9. Definição de classe
    1. Regra – Um projeto deve usar uma definição de classe consistente
    2. Definição -Classes devem refletir somente a solução no escopo a que ela se propõem
    3. Definição -Não crie métodos estranhos ou classes publicas
    4. Definição -Minimize a função provida por uma classe
    5. Definição -Concidere diferenças entre atributos hiding e métodos overloading
    6. Atenção -A referencia super é equivalente ao uso de casting com this
    7. Regra -Evite o uso de parâmetros em métodos que conflitem com atributos da classe
  10. Construção de classe
    1. Construtor
      1. Regra -Sempre inicialize a superclasse e caso necessário os atributos
      2. Regra -Não inicialize atributos estáticos dentro do construtor
      3. Definição -Minimize as funções providas pelos construtores
  11. Encapsulamento e controle de acesso
    1. Regra -Não mude a visibilidade de um método em uma classe derivada
    2. Definição -Maximize o uso de encapsulamento de atributos(private)
    3. Definição -Nunca crie referencias diretas para os atributos da classe
    4. Definição -Criação de atributos abstratos
    5. Definição -Use com atenção a definição de visibilidade para um atributo
    6. Regra -Evite mais de dois níveis de aninhamento de classes
  12. Herança
    1. Regra -Mova os códigos em comum para dentro de uma hierarquia
    2. Regra -Mova código comum para dentro de métodos privados
  13. Herança de métodos
    1. Padrões e convenções para métodos
      1. Regra -Chame método estático com operador de escopo
      2. Definição -Overload on type whenever it’s possible
    2. Tipo de retorno
      1. Definição -Retorne um arrays de objeto com tipo
  14. Gerenciando Exception
    1. Regra -Previna seu programa de erros
    2. Regra -Evite blocos "catch" em corpo vazio
  15. Diversos
    1. Definição -Evite o use de referencias nulas
    2. Regra -Minimize o uso de tipos primitivos
    3. Definição -Cuidado ao usar concatenação de Strings com tipos variados
    4. Definição -Arrays podem ser irregulares
    5. Regra -Usando JDBC sempre utilize a chamada ao método close() após utiliza-lo
    6. Regra -Evite concatenação de String com « += »
    7. Regra -Evite o uso do operador de negação '!'mais do que 3 vezes dentro de um método
    8. Regra -Evite que atributos estáticos que não final tenham seu valor alterado durante a inicialização
    9. Regra -Evite atribuições a parâmetros de métodos
    10. Definição -Classes que somente tenham métodos abstratos e campos do tipo 'static final' deve ser definida como 'interface'
    11. Regra -Evite chamar métodos que não sejam final, static ou private dentro do construtor
    12. Regra -Evite utilizar String.equals ('literal'), use 'literal'.equals (String)
  16. Performance
    1. Regra -Evite usar a keyword 'new' quando criar objetos do tipo String para armazenar literais
    2. Regra -Evite criação desnecessária de objetos para converter tipos primitivos em String
    3. Definição -Evite o uso de 'Date[]', use 'long[]'
    4. Regra -Evitar 'static' collections
    5. Regra -Use abreviações de operadores
    6. Definição -Evite chamar métodos dentro do statement de condição de um loop
    7. Regra -Uso do operador condicional 'if (cond) return; else return;'
    8. Regra -Uso do operador condicional 'if (cond) a = b; else a = c;'
    9. Regra -Use 'charAt()'ao invés de 'startsWith()'para comparação de um caracter
    10. Definição -Evite chamadas de métodos 'synchronized' em um loop
    11. Definição -Coloque blocos 'try/catch' fora dos loops
    12. Regra -Evite desnecessários casting
    13. Regra -Use variáveis 'stack'sempre que possível

Sobre esse Tutorial

Néki Technologies.

Agradecimentos ao Néki Team!

Objetivo

O objetivo deste documento é auxiliar o programador no desenvolvimento de projetos utilizando a linguagem Java.

Escopo de Aplicação

Este documento é aplicável a todos os projetos de desenvolvimento de software realizados em Empresas que utilizam a abordagem de Orientação a Objeto (OO).

Descrição Sumária

Este documento apresenta o Padrão de Codificação da Linguagem JAVA.

Os padrões para codificação de programas visam garantir que todos os desenvolvedores envolvidos no desenvolvimento e/ou manutenção de sistemas, entenderão com facilidade o objetivo e funcionamento de cada programa.

Os padrões devem proporcionar:

  • Agilidade no desenvolvimento, através do aproveitamento de templates e programas préexistentes.
  • Redução de riscos. Adotando padrões bem definidos e já testados diminui-se o risco de erros
  • funcionais, desvios de performance etc...
  • Clareza do código fonte, permitindo que um programador que não tenha participado diretamente do desenvolvimento de determinada aplicação entenda com facilidade o objetivo e o funcionamento dos programas;

Através do padrão adotado estaremos portanto disponibilizando:

  • Programas estruturados e com menos riscos de erro;
  • Programas desenvolvidos mais rapidamente;
  • Programas mais fáceis de alterar, sem risco de comprometimento da estrutura original;
  • Programas testados integralmente e em tempo menor.

Mesmo tentando estabelecer padrões rígidos e detalhados, em diversas situações não será possível aplicar integralmente o padrão geral, seja por limitações de espaço em tela, por particularidades do programa ou pela facilidade de operação que um desvio de padrão poderá conferir ao programa. Em todo caso, porém, um desvio no padrão definido nesse documento deverá ser discutido previamente com o analista responsável.

Acrônimos

Acrônimos:

ACRÔNIMO (Ordem Alfabética)SIGNIFICADO / DESCRIÇÃO  
OOOrientação a Objeto.

Papéis / Áreas Funcionais e Responsabilidades

PAPÉIS/ÁREAS FUNCIONAIS RESPONSABILIDADES
ProgramadoresDesenvolver o Código-Fonte da aplicação de acordo com as instruções do documento de padronização.

Instruções Operacionais

Prefácio

Este documento foca em regras para desenvolvimento de softwares coorporativos que exijam padronização.

Introdução

Este documento apresenta regras que ajudarão a desenvolver e melhorar o estilo e estrutura dos seus códigos Java. Ele foca em pontos comuns de erro cometidos pelos desenvolvedores de software que diretamente afetam a qualidade do código. É importante lembrar que a qualidade do software esta diretamente associada à forma de manutenção, performance e portabilidade de problemas, os quais podemos prevenir e/ou capturar, reduzindo o tempo gasto no futuro através de debug ou otimização de código, através da utilização desse documento.

O uso deste documento também ajudará a novos desenvolvedores entenderem a padronização e o nível de expertise código. Eles não verão somente regras associadas com a qualidade na programação Java, mas o "entendimento" atrás das regras utilizadas.

Muitas regras e definições usadas neste documento contem informações redundantes. Isto foi feito com o intuito de poder ser usado sem a necessidade de ler regras anteriores.

Objetivos dessas definições e regras

  1. Aumento de Produtividade
    1. Prover direções na melhoria do desenvolvimento de código Java.
  2. Melhorias sem impacto.
  3. Permite que design e codificação mudem com o mínimo de impacto no código.
    1. Abstração.
      1. O uso de abstração permite uma mudança transparente.
    1. Implementações Late Binding.
      1. Permite que tipos de dados sejam resolvidos em tempo de run-time.
  4. Aumento de Qualidade.
  5. Permite o aumento de qualidade como um código mais legível. Legibilidade implica em uma taxa baixa de erros.

Quem deve ler esse documento

Qualquer pessoa envolvida em projetos que estejam usando ou planeje usar Java, como linguagem de desenvolvimento para a construção de aplicações. Esse documento é diretamente técnico para lideres e desenvolvedores.

Pré-requisitos

Será assumido um conhecimento básico da linguagem Java.

Estrutura do Documento

Este documento agrupa seus pontos em tópicos específicos. Os pontos estão em formas de regras ou definições. As regras devem "quase" nunca serem quebradas, em quanto às definições podem ser violadas com mais freqüências. Caso alguns tipos de padronização não façam sentido no projeto em desenvolvimento, esses devem ser ignorados e podem ser evoluídos durante o processo de desenvolvimento.

Nome de Arquivo e Convenções da Estrutura

Nome de arquivo

Regra -Todos os arquivos fontes devem ter a extensão .java

O compilador Java requer que todo arquivo fonte tenha a extensão "java"

Exemplo:

javac MyClass.java

Nota: Para sistemas que suportam somente nome de arquivo 8.3, a extensão "jav" é usada.

Regra -Todas as classes Java devem conter a extensão .class

O compilador java gera arquivos binários com a extensão "class".

Exemplo:

Este exemplo roda MyClass.class:

java MyClass

Nota: Para sistemas que suportam somente nome de arquivo 8.3, a extensão "cla" é usada.

Regra -Nome do Package deve servir como mapa para o nome dos arquivos Java

Cada sub-nível dos nomes do package é mapeado para um nome de diretório no sistema operacional, portanto esse nomes devem ser suportados pela estrutura de arquivos do S.O. Use somente caracteres alpha e numéricos nesses nomes.

Exemplo:

Considere o package:

package mystuff.myclasses;

Ele será mapeado para o determinado diretório no S.O.:

...\mystuff\myclasses

onde “...” é o caminha criado para os fontes Java.

Definição -Criação de packages para a organização de classes

Java permite classes e/ou interfaces sejam agrupadas em packages. Packages são hierarquicamente um modo de organizar classes. Serviços ou classes que compõe um simples programa deve ser colocado em seu próprio package. Veja por exemplo o package de classes do Java.

Nota: Todos os packages desenvolvidos na Empresa deverão seguir a nomenclatura com.[nome_da_empresa_abreviado].[nome_do_projeto].[outras_identificacoes].

Exemplo:

Imagine que você precise criar um package que contenha classes para acessar o banco de dados do projeto XPTO, da empresa ACME. Essa nomenclatura provavelmente ficaria:

com.acme.xpto.persistencia

Estrutura dos arquivos

Definição -Gerenciando referencias em ciclos

Uma referencia em ciclo é onde uma classe A tem uma variável que é instancia de uma classe do tipo B e B tem uma variável que é instancia de uma classe do tipo A.

Exemplo:

package com.acme.dados;
// Java1 referencia Java2 e vice-versa
class Java1 {
Java2 aJava2;
Java1() {
aJava2 = new Java2();
}
void method1() {
aJava2.method1();
}
}
class Java2 {
Java1 aJava1;
Java2() {
aJava1 = new Java1();
}
void method1() { 
aJava1.method1(); 
} 
} 

Se este relacionamento é requerido, então ambas as classes ficam no mesmo arquivo fonte. Se ambas as classes precisam ser publicas, então coloque cada classe em arquivos separados, mas usando o mesmo package.

Definição -Número de classes por arquivo

Em geral, deve ser somente uma classe por arquivo. Isso permite que o arquivo fonte combine com o nome da classe, portanto seja mais fácil de localizar o arquivo fonte. Dessa forma, classes relacionadas devem ser colocadas no mesmo package, mas não no mesmo arquivo.

Caso existam várias classes no mesmo arquivo, o nome do arquivo tem que ser o mesmo da única classe publica existente nesse arquivo. As outras classes precisam ser privadas ou classes somente visíveis para o package.

Exemplo:

Para o arquivo fonte MyClass.java:

public class MyClass {
...
}
class InternalClassA {
...
}
class InternalClassB {
...
}

Regra -Especificar os tipos de import

Importe classes e não packages.

Exemplo:

import mypackage.MyParameterClass; 
import otherpackage.OtherClass; 
class MyClass { 
... 
public void method( MyParameterClass oX ) { 
... 
} 
... 
} 

Isso reduz a chance onde duas classes dividem o mesmo nome, e você use a classe errada.

Regra -Tamanho dos métodos

Os métodos devem ser o menor possível, para possibilitar legibilidade e manutenibilidade. Considere mover if, while e for para métodos privados. Métodos grandes não são aceitos em OOP.

Regra -Não declare múltiplas variáveis de tipos diferentes em um único statement

Declaração de múltiplas variáveis em um único statement é confuso.

Exemplo:

package com.acme.projeto.dados; 
class VDT { 
private int index, index1[]; // VIOLACAO 
public void method () { 
int aaa, bbb[]; // VIOLACAO 
int ccc; 
int ddd; 
} 
} 

Reparar:

Use declaração de statements separados para variáveis de tipos diferentes.

package com.acme.projeto.dados;
class VDTFixed {
private int index; // INDICADO
private int index1[ ]; // INDICADO
public void method () {
int aaa; // INDICADO
int bbb[ ]; // INDICADO
int ccc;
int ddd;
} 
} 

Regra -Evitar assinatura de métodos com muitos parâmetros

Uma grande quantidade de parâmetros indica complexidade para interfacear a chamada a objetos e deve ser evitado. Propomos uma limitação de 5 (cinco), o numero de parâmetros recebidos por um método.

Definição -Escreva um statement por linha

Se essa formatação for seguida por todos, isso facilitará a leitura do código por outras pessoas.

Exemplo:

package com.acme.format; 
public class OSPL { 
int method (int a, int b) { 
int i = a + b; return i; // VIOLACAO 
} 
} 

Reparar:

package com.acme.format; 
public class OSPLFixed { 
int method (int a, int b) {
int i = a + b; //INDICADO
return i; // INDICADO
} 
} 

Documentação

Arquivo e descrições

Regra -Use uma tag padrão para indicar mudança

Uma vez que um arquivo fonte mude o controle das ações, todas as modificações requerem algum fixamento de erro ou aprovação de mudança de design. Este arquivo alterado deve ter seu objetivo modificado, explicando qualquer alteração, adição ou revisão que tenha ocorrido no arquivo. Suas descrições devem ser colocadas na seção de revisões.

Exemplo:

/** Pequena descrição do objetivo. 
* 
* 
* @copyright (C) ACME Corp.
*
* @security unclassified
*
* @author I. M. Smart 
* @date 01/01/96 
* @revision DCR001 
* date 10/01/96 by: B. A. Feigenbaum 
* reason Adicionar a instancia de um contador 
* 
* @revision PTR001 
* date 10/10/96 by: I. M. Smart 
* reason Adicionar construtor default
*
* @revision DCR002 
* date 10/20/96 by: B. A. Feigenbaum 
* reason Remover o proprietario de endereço 
**/ 
public class Account { 
// instance count 
static int count; 
// account id 
int id; 
// account value 
double value; 
// account owner 
String name; 
// default constructor 
public MyClass() {
// count myself
count++;
value = 0.0;
name = "";
} 
// constructor 
public MyClass( String name, double value ) { 
// count myself
count++;
value = value;
name = name;
} 
// constructor 
public MyClass( String name ) {
// count myself
count++;
value = 0.0;
name = name;
}
// destructor 
public finialize() {
// discount myself
count--;
}
...
}

Regra -Use prefácios para padronização de classes, métodos e campos

Veja exemplo de prefácios para padronização sugerido para classe, métodos e campos.

Qualquer comentário começa com blocos /** para ser processado em documentação através da utilização de ferramentas como javacdoc.

Essas linhas devem seguir as seguintes definições para classe:

tag

Função

  • @author - Author de criação.
  • @date - Data de criação
  • @see - Cria um "See also:" um hyperlink para o nome e descrição do nome da classe.
  • @see # - Cria um "See also:" um hyperlink para o nome do método e descrição
  • @param - Adiciona uma linha para a seção parâmetros, descrevendo cada parâmetro nela.
  • @return - Cria uma linha de Returno associada com o mesmo.
  • @exception - Adiciona uma linha para o "Throws:" na seção de exception e descrevendo a mesma.

Exemplo:

Prefacio da Classe:


/* (C) Copyright by ACME Corp. 
* All Rights Reserved. 
*/ 
/** Descrição da classe.
*mais texto se necessário.
*
* @author X. Y. Zzzzzzzzzzzzzzz 
* @date dd/mm/yyyy 
* @see OutraClasse 
* @revision 001 
* date dd/mm/yyyy 
* author X. Y. Zzzzzzzzzzzzzzzzzzzz 
* reason pequena descrição
**/


Prefacio do método:

/** 
* Breve descrição 
* Descrição da função 
* Incluir a descrição sobre o algoritmo caso não trivial
*
* @return descrição do valor de retorno 
* @param arg1 descrição do arg1 
*: :: 
* @param argN descrição do argN 
* @exception full.exception.ExceptionName1 significado da exception1 
*: : 
* @exception full.exception.ExceptionNameN significado da exceptionN
*
* @see AnotherClass#AnotherMethod 
* @author X. Y. Zzzzzzzzzzzzzzz 
* @date dd/mm/yyyy
**/
modifiers returnType name(argType1 arg1, ..., argTypeN argN) throws ExceptionName1, ..., 
ExceptionNameN { 
// corpo do método 
} 


Prefacio do campo:

/** 
* Descrição do campo.
**/

Notas:

  1. Breve sentença descritiva não deve conter períodos anteriores.
  2. @return é omitido para void, constructor, e métodos finalize.
  3. @param é omitido se não existe parâmetro.
  4. @exception é omitido se não são lançadas exception.
  5. @author é omitido no caso do mesmo autor da classe.
  6. As descrições das classes, métodos e revisões devem ser escritas em português.
  7. Todas essas descrições devem ser descritas após os statements de import.

Regra -Um projeto deve adotar um estilo de comentário consistente

Todos os comentários devem ser feitos em português usando //. /* somente serão usados para cunho de debug.

Sempre incluir pelo menos um espaço em branco após o // introdução do comentário. Isso melhora a legibilidade.

Nota: Comentários devem ser identificados com o código fonte e nunca colocar "fim" no final das linhas.

Definição -Alinhar elementos de definição de classes/interface

As várias partes de cada entrada em uma classe ou interface deve estar alinhada. Tipos, variáveis/métodos, devem começar na mesma coluna. Com isso fica mais fácil achar os diferentes elementos.

A endentação e feita automaticamente pelo WSAD, Eclipse e outras IDEs Java existentes no mercado. Use a endentação de 4 caracteres.

Exemplo:

public class MyClass {
// class variables
// instance counter
private static int iCount = 0;
// instance variables
// a value 1
private int iVariable1;
// a value 2
private int iVariable2;
// a value 3
private int iVariable3;
// an object 4
private ALongTypeNameXXX oVariable4;
// methods 
// a method 1 
public int method1() {
:
}
// a method
public int aLongMethodNameThatKeepsGoingAndGoing() {
:
}
// arg1 description
// arg2 description
// arg3 description
public void method2( int arg1, LongName arg2, char arg3 ) {
: 
} 
} 



Nota: O conteúdo da classe deve também ser endentado usando quatro espaços em branco.

Estrutura de Controle

Regra -Não use operador ternário dentro de outras funções

O operador ternário é somente para atribuições "puras".

Exemplo:

class MyClass {
int iX ;
void changeX (boolean bCondition) {
x = (bCondition == true) ? 0 ? 1 ;
}
}


O exemplo abaixo não é aceito:

import com.acme.*; 
class Application { 
private Portable portable; 
public static void main( String[] args ) {
// select platform here
Application a = new Application( System.os.equals("Linux") 
? new LinuxPortable() 
: new WinPortable() 
); 
a.doIt();
}
public Application( Portable p ) {
portable = p;
}
public void doIt( ) {
:
// o mesmo para todas as plataformas
portable.nonPortableMethod();
:
} 
} 

Regra -Todos os switch statements devem conter um default case

O uso do default no case faz o fluxo de controle explícito quando não existe uma combinação para o label em questão. Isso torna mais fácil para os desenvolvedores determinarem quando um label usado no case deve ser adicionado ou removido inadvertidamente.

Regra -Uso explicito de comparação dentro de testes condicionais

Statements de expressões condicionais em estruturas de controle devem ser explicitadas. Em Java, expressões condicionais devem conter valores dos tipos char, byte, short, int.

Exemplo:

int counter = 100;
Object o = ...;
// Explicitando os estados condicionais das expressões:
while(counter != 0) ...
if(o != null) ...
// isto é ilegal:
// integers não são booleanos
while(counter) ...
// sem ponteiros na linguagem
if(!o) ...

Regra -Estruturas de controle aninhadas

Endente com 4 espaços em branco dentro da estrutura de controle, delineando entre o fechamento da estrutura de controle e seus blocos de statements. A codificação é muito mais fácil de ler se o loop, case e statements de condição estão organizados. Todos os statements após um if, else, while, do, for, switch, ou case devem estar endentados. Todos os statements dentro de um bloco (ex:, {e}) devem estar endentados.

A endentação sugerida é para 4 caracteres. Isto permite uma fácil separação visual, mesmo para significantes aninhamentos sem precisar endentar muito para a direita. Para linhas continuas endente oito espaços em branco ou alinhe o texto continuo com o similar texto da linha anterior.

// endente seus blocos de controle...
int j;
for(j = 0; j < 10; j++) {
	int i;
	for( i = 0; i < 10; i++ ) {
		System.out.println("I = " + i + ", J = '+j+ ", I * J = " + (i * j));
	}
}
if(i == 0) {
:
}
else {
:
}


Nota: Mesmo não sendo de obrigação da linguagem, é preferido que todos os blocos de if, else, for e while mesmo quando tenham somente um único statement, usem chaves para abrir e fechar o bloco. Considere:

int i; 
for(i = 0; i < 10; i++) {
	System.out.println("I = " + i);
}

Definição -Adotar um consistente estilo de endentação e abertura e fechamento de blocos de controle

Existem vários outros estilos de organizar essas estruturas, mas a seguinte é a sugerida pelo NÉKI Group.

Use o seguinte estilo para statements if:

Exemplo:

// Para varios blocos de statement
if(expr) {
statements
}
else {
statements
}

Use o seguinte estilo para statements for:

Exemplo:

// Para vários blocos de statement
for( expr; expr; expr ) {
statements
}


Use o seguinte estilo para statements while:

Exemplo:

// Para vários blocos de statement 
while( expr ) { 
statements 
} 


Use o seguinte estilo para statements do:

Exemplo:

// Para vários blocos de statement
do {
statements
} while( expr );


Use o seguinte estilo para statements switch:

Exemplo:

switch( expr ) { 
case 1: {
// statements
break;
} 
case 2: {
// statements
break;
}
:
case N: {
// statements
break;
// requerido mesmo se vazio
default: {
// statements
break;
}
}


Use o seguinte estilo para statements try:

Exemplo:

try {
// código para ser tentado
} catch( Exception e ) {
// código fixado
} finally {
// código para ser limpo
}


Use o seguinte estilo para método:

Exemplo:

// Para vários blocos de statement
type doSomething() {
statements
}
--ou -// 
para simples statements de métodos
type doSomething() {
statement
}

Nota:

  1. Evite usar try-catch para fazer com que métodos tenham throws Exception em sua assinatura.
  2. Sempre use chaves, mesmo se o comando contenha somente um statement.

Definição -Termine cada bloco case com um statement break

Se um statement break não for especificado em cada bloco case, então todas as linhas de códigos associadas ao bloco que seguem o case serão executadas. Isto geralmente não é a intenção do desenvolvedor.

Definição -Overflows/underflows sobre sinais aritméticos

Quando usar signed number seja cuidadoso para planejar os limites da faixa e os possíveis overflows.

Considere as faixas:

TipoFaixa
byte -128 até +127
short -32,768 até +32,767
int -2,147,483,648 até +2,147,483,647
long -9,223,372,036,854,775,808 até +9,223,372,036,854,775,807

Por exemplo, se você adiciona 1 para um byte com um valor corrente de 127 você pode ter um resultado de 128, não +128. Considere:

byte i = 127;
:
i++;
System.out.println("i is " + (i < 100 : "less" : "greater") + "than 100");
:


A saída do código: i is less than 100.

Regra -Coloque constantes no lado esquerdo das comparações

Uma digitação comum enquanto escrevendo código é usar "=" ao invés de "==" em operações de igualdade. Colocando constantes no lado esquerdo da comparação, isso ira fazer com que o compilador de uma mensagem de erro. Por exemplo, o compilador java dará uma mensagem de erro para: if(false = var) mas não para: if(var = false).

Exemplo:

package com.acme.projetos.dados; 
public class CLS { 
public void testMethod (int something) { 
if (something == 5) {} // VIOLACAO 
} 
} 


Reparar:

Coloque constantes do lado esquerdo das comparações.

package com.acme.projetos.dados; 
public class CLSFixed { 
public void testMethod (int something) { 
if (5 == something) {} // INDICADO 
} 
} 

Regra -Declare 'for' loops com uma condição e statement de incremento

Se um incremento ou a condição de checagem é verificada fora do loop, estes não devem ser usados.

Se a condição e o incremento estão no corpo do loop, esta sendo usado um estilo pobre.

Exemplo:

package com.acme.projetos.dados; 
public class PCIF { 
void method (int i) { 
for (; i < 1000; ) { // VIOLACAO: incremento não é feito no loop 
i++; 
} 
} 
} 


Reparar:

Verifique se a condição ou a expressão de incremento está perdida ou simplesmente estão no corpo do loop. Se a expressão esta perdida, ou substitua-a, ou substitua o statement for por um statement while.

package com.acme.projetos.dados; 
public class PCIFFixed { 
void method (int i) { 
while (i < 1000) { // INDICADO 
i++; 
} 
} 
} 

Regra -Evitar atribuições dentro de uma condição if

Atribuições em muitos tipos de statements condicionais em Java, são ilegais porque eles são fáceis de causar acidentes com os seus tipos. Seguindo estas regras ajuda a manter a conformidade e evitar erros.

Exemplo:

package com.acme.projetos.dados; 
public class ASI { 
public int foo (boolean b) {
int ret = 0;
if (b = true) { // VIOLACAO
ret = 3;
}
return ret;
} 
} 


Reparar:

Mude a atribuição de valor a variável para um statement separado ou se isso foi um erro, substitua por "==" operador de comparação.

package com.acme.projetos.dados; 
public class ASIFixed { 
public int foo (boolean b) {
int ret = 0;
if (b == true) { // INDICADO
ret = 3;
}
return ret;
} 
} 

Regra -Evitar statements 'for' com corpo vazio

Statements "for"que são seguidos imediatamente por ponto e virgula, não é uma boa pratica.

Exemplo:

package com.acme.projetos.dados; 
public class FEB { 
void method () { 
for (int i = 0; i < 10; i++) ; // VIOLACAO 
System.out.println (i); // este statement fora do loop 
} 
} 

O 'println ()'será executado uma unica vez após o loop.

Reparar:

Remova o ponto e virgula no fim do loop.

package com.acme.projetos.dados; 
public class FEBFixed { 
void method () { 
for (int i = 0; i < 10; i++) // INDICADO 
System.out.println (i); // este statement esta dentro do loop 
} 
} 

Regra -Não atribua valor a variáveis de controle dentro do corpo de um 'for' loop

Uma variável de controle de um "for" loop deve somente ser modificada na inicialização e expressão de controle do statement "for" loop. Modificando-a no corpo do loop faz o código difícil de entender e pode contribuir para erros.

Exemplo:

package com.acme.projetos.dados; 
public class FLVA { 
int method () {
int sum = 0;
for (int i = 0; i < 100; i++) {
i += 3; // VIOLACAO
sum += i;
} 
} 
} 


Reparar:

Reescreva o código para que as variáveis de controle do "for" loop não precisem ter valores atribuidos no corpo do loop.

package com.acme.projetos.dados; 
public class FLVA { 
int method () {
int sum = 0;
for (int i = 0; i < 100; i += 4) { //INDICADO
sum += i;
}
return sum;
} 
} 

Regra -Evitar statements 'if' com corpo vazio

Se um statement "if" estiver seguido imediatamente por um ponto e virgula, não é uma boa pratica.

Exemplo:

package com.acme.projetos.dados; 
public class IEB { 
void method (int i) { 
if (i < 0) ; // VIOLACAO 
System.out.println("negative i"); // Isto sempre acontecera 
} 
} 

O 'println ()'sempre acontecera independente do valor de 'i'.

Reparar:

Remova o ponto e virgula desnecessario.

package com.acme.projetos.dados; 
public class IEBFixed { 
void method (int i) { 
if (i < 0) // INDICADO 
System.out.println("negative i"); 
} 
} 

Convenção para identificação de nome

Convenções gerais para identificação de nome

Regra -Convenção de nomes para os elementos de um programa

Isso faz o código torne mais legível e evita alguns comentários. Java não tem limite para o nome de classes, métodos ou variáveis. Seguem algumas regras sugeridas para compor os nomes:

  1. Para constantes use sempre letras maiúsculas separando os nomes por underscore. Por exemplo: MAX_VALUE.

    Nota: Constantes são variáveis para serem definidas como final e static. Em geral as constantes devem ser utilizadas para representar literais.

    Para variáveis locais e parâmetros utilize letras minúsculas para o primeiro nome. Não use nomes abreviados. O uso de caractere único nos nomes, somente para indicar o tipo:

    a Para array object
    b Para byte
    c Para char
    d Para double
    dt Para date
    e Para exception object
    f Para float
    i Para int
    i, j, k, ... Para índice de for loop
    l Para long
    o Para qualquer object
    s Para string object
    v Para uso geral


    Nota: O nome da variável deve ser totalmente legível.
  2. Para métodos use letra minúscula no primeiro nome. Métodos com funções comuns devem usar nomes comuns (em Inglês):

    get campo get()
    set campo set(type arg)
    get length length()
    condição is()
    Conversão de formato to()
    Gerenciar ações on()


    Métodos que se utilizam de factory newInstance()
  3. Para nomes de classes e interface, use letra maiúscula na primeira letra do nome. Use nomes descritivos. Para interfaces, o nome deve ser um adjetivo.

    //TODO:

    Tipo de classe Padrão do nome Uso
    Servlets Serv....... Para o uso com servlets
    Services ... BO Para classes que representam regra de negócio
    Batch Bt.... Para aplicações batch, classes que tem o método mais e são executadas off-line
    Structure ...VO Para classes que são estrutura de dados, que são passadas entre os servlets, JSP, Sv e Db
    DB ... DAO Para classes que acessam os banco de dados
    JSP ..... .jsp; Para os arquivos JSP’s, deve ser adotado a mesma convenção que as classes java
    Session Beans SL…. Para session beans
    Entity Beans EC Para entity beans
  4. Para nomes de package, use letras minúsculas em todos os nomes.

    Exemplo: com.acme.infra.

    Nota: Essas regras são baseadas em convenções providas em The Java Language Specification by James Gosling, Bill Joy and Guy Steele. Variaveis e atributos devem sempre começar com letra minúscula, iniciando com maiúscula cada palavra subseqüente que forme o nome. O nome deve conter quantas palavras quanto necessário para fazer o nome entendível.

    Exemplo:

    class ClassName {
    // base value
    int iVariable1;
    int iVariable2;
    int iVariable3;
    // object
    MyClass oMyClass;
    public ClassName( int newVariable1, int newVariable2, int newVariable3 ) { 
    variable1 = newVariable1;
    variable2 = newVariable2;
    variable3 = newVariable3;
    }
    }
    

Definição -Não redefinir um identificador que já tenha sido declarado em um mesmo delimitador de escopo

Redefinições de nomes em diferentes escopos, somente traz confusões para quem estiver lendo o código. Se uma declaração da variável for removida do escopo aninhado, então o código deve inadvertidamente alterar o conteúdo da variável que esta no escopo acima, trazendo conseqüências inesperadas.

Exemplo:

void member() {
double x = 0.1;
for(int i = 100; i < 0; i--) {
// esqueça esse tipo de declaração
int x = 1000;
:
// será uma divisão inteiro; não float como deve ser esperado
x /= i;
}
// resposta é 0.1
System.out.println("The result is " + x);
} 

Definição -Variáveis de loop devem ser identificadas como i, j, k, ...

Usando os labels i, j, k e assim por diante como variáveis de loop é uma convenção que é resultado de tradição. O uso desses labels devem ser uniformes por todo os códigos do projeto, tornando assim fácil e rápido a identificação de variáveis de controle do loop.

Definição -Explicitar o tempo de vida de uma variável de controle

O tempo de vida de um variável de controle no statement for é a duração do loop. Se você necessita de um tempo maior do que o declarado no controle do loop, declare a variável de controle fora do loop, mas seja cuidadoso com isso, lembre, declare a variável dentro do escopo do loop, sempre que possível.

Exemplo:

class SomeClass {
:
public void someMethod() {
:
// i existe até o fim do for
for( int i = 0; i < 100; i++ ) loop{
: 
if(/* some condition */) {
break;
:
}
// erro -i não esta declarado aqui
if( i < 100 ) {
/* some action */;
:
}
:
}
}


Código alternativo:

class SomeClass {
:
public void someMethod() {
// i existe até o fim do someMethod
int i;
:
for( i = 0; i < 100; i++ ) {
:
if( /* some condition */ ) {
break;
: 
}
// OK -i existe
if( i < 100 ) {
/* some action */; 
:
}
:
}
}

Convenção de nomes para classes e interface

Regra -Todos os nomes devem começar com letra maiúscula

Todos os nomes para classes e interface devem começar com letra maiúscula e os nomes subseqüentes devem iniciar também.

Exemplo:

class PointXY { 
:
}
class Human {
:
}
interface MemberOfPool {
:
}
PointXY oPointXY;
Human oHuman;
MemberOfPool oMemberOfPool;
Integer i;
Color oColor;

Convenção de nomes de campos

Definição -Definindo array de um determinado tipo

Se você conhece a quantidade de objetos a serem armazenadas, use array, caso contrario use:

  • Enumeration, Collection, ArrayList -pode usar repetição;
  • Hashtable -não pode usar repetição.

Os colchetes devem ser colocados a direita após o tipo da variável e nunca após o nome.

class SomeClass {
:
// aSomeField é um array do tipo inteiro
public int[] aSomeField = new int[10];
// aSomeVector é um vector
public Vector aSomeVector = new Vector();
{ 
:
}
:
} 


Use 'L' ao invés de 'l' para expressar constantes do tipo long

Constantes inteiras são long se você colocar no fim da declaração o "L" ou "l". É preferível usar o "L" ao invés de "l", pois o "l" pode ser confundido com o numero um.

Convenções para nome de métodos

Regra -Todos os nomes de métodos devem começar com letras minúsculas

Comece o nome do método com letra minúscula e coloque letra maiúscula para todas as palavras subseqüentes.

Exemplo:

boolean isEmpty() { 
...
}
File findFile() {
...
}

Regra -Não inclua o nome do tipo no nome do método

Métodos são identificados pelo objeto no qual ele esta agindo. Não existe a necessidade de identificar a classe no nome do método.

MyClass myClass;
// foo
myClass.foo();


Nunca use estas formas:

myClass.fooMyClass();
--ou --
myClass.myClassFoo();


Lembre que Java realiza overload de métodos para tipos de parâmetros diferentes:

static long max( long x, long y );
static double max( double x, double y );


ao invés:

static long maxl( long x, long y );
static double maxd( double x, double y );

Regra -Use static final na declaração de constantes

O uso de static e final no modificador de acesso de uma variável faz com que seja imutável seu valor, definindo assim uma constante.

Exemplo:

class MyConstants {
// constante String
public static final String JOHN_DOE = "John Doe";
// constante int
public static final int JOHN_DOE_ID = 100;
:
} 


Fora da classe essas constantes são referenciada como:

: 
String myName = "Barry Feigenbaum";
int myID = -1;
if(myName.equals(MyConstants.JOHN_DOE)) {
myId = MyConstants.JOHN_DOE_ID;
:
if(myID < 0) {
// Realiza algo
}
:
} 


Note: Isso é usado especialmente para constantes do tipo String. Permite que todas as constantes do tipo String sejam colocadas em um unico arquivo, facilitando a "tradução".

Definição -Use prefixos comuns e consistente para métodos

São usualmente utilizados para expressar efeitos que indiquem o objetivo do método:

prefixos Tipo de método
get Prefixo para retornar um atributo de um método.
set Prefixo para modificar o atributo de um objeto.
query Prefixo para retornar um valor de um objeto que não deve ser modificado.
to Prefixo para conversão de métodos como toString().
on Prefixo para métodos que gerenciam eventos, como onButtonPress().
is Prefixo para checar tipo/estado como isValid(). Esses métodos retornam um valor booleano.
newInstance; instance; getInstance Nome para métodos de factory.


Exemplo:

class ClassName {
// variaveis
int iVariable1;
int iVariable2;
// acesso
public int getVariable1() {
return variable1;
}
// atribuição
public void setVariable1( int newVariable1 ) {
variable1 = newVariable1;
}
//
public boolean isReady() {
return variable1 == variable2;
}
}

Definição -Use nomes descritivos para os parâmetros dos métodos

O nome dos parâmetros deve indicar seus objetivos. Nomes consistentes são fáceis de serem distinguidos dos atributos.

Exemplo:

Use o qualificador this (new in Java Beans)

public class SomeClass { 
private int field1; 
:
private int fieldN;
:
public SomeClass( int newfield1, ..., newfieldN ) {
// this.setfield1 é o atributo
// newfield1 é o argumento
this.setfield1 = newfield1;
:
this.setfieldN = newfieldN;
}
:
}

Definição de classe

Regra – Um projeto deve usar uma definição de classe consistente

A aparência da classe é importante. Apesar da IDE Java gerenciar a geração do código, é importante termos a idéia da formação da estrutura de uma classe.

//TODO:

Exemplo:

Sugestão da estrutura de uma classe

class <name extends <superclass> implements <interfaces> {
// public atributos e métodos visíveis
public static final data members
public static data members
public data members
public constructors
public finialize
public static methods
public methods


Nunca use :

// Atributos e métodos visíveis somente para o package
static final data members
static data members
data members
constructors
static methods
methods
// package visibilidade protected para atributos e métodos
protected static final data
protected static data
protected data
protected constructors
protected static methods
protected methods


Nunca use:

// visibilidade protected para atributos e métodos
private protected static final data
private protected static data
private protected data
private protected constructors
private protected static methods
private protected methods
// visibilidade private para atributos e métodos
private static final data members
private static data members
private data members
private constructors
private static methods
private methods
}


Note: Nunca use private protected para os modificadores de acesso.

Definição -Classes devem refletir somente a solução no escopo a que ela se propõem

Criar classes que modelem entidades no seu limite de domínio, não existe a necessidade de abranger várias soluções em uma única classe.

Definição -Não crie métodos estranhos ou classes publicas

Não crie classes ou métodos que estejam prontos para serem usados. Entenda se existe a real necessidade de declara-los como publico, disponibilizando seu uso.

Definição -Minimize a função provida por uma classe

Cada classe deve ser atômica. Uma classe deve ser única. Não misture vários objetivos dentro de uma classe. Se combinações são necessárias, use interface para especificar as combinações.

Exemplo:

Definição de interface:

package persistence;
import java.io.IOException;
import java.io.DataOutputStream;
import java.io.DataInputStream;
public interface Persistent {
// saves object to file
public boolean storeOn( String f )
throws IOException;
// saves object to stream
public boolean storeOn( DataOutputStream s )
throws IOException;
// gets object from file
public boolean loadFrom( String f )
throws IOException;
// gets object from stream
public boolean loadFrom( DataInputStream s )
throws IOException;
}


Um uso de interface:

import persistence.Persistent;
import application.AppClass;
public class MyClass implements Persistent {
private int value1;
// AppClass implementa Persistent tambem
private AppClass class1;
:
public boolean storeOn( String f ) throws IOException {
DataOutputStream s = new DataOutputStream( BufferedOutputStream(
FileOutputStream( f ) ) );
boolean result = storeOn( s );
s.close();
return result;
}
public boolean storeOn( DataOutputStream s ) throws IOException {
// put int
s.writeInt( value1 );
if( class != null ) {
// indicate AppClass present
s.writeBoolean( true );
// put instance
class1.stroreOn( s );
else
// indicate AppClass missing
s.writeBoolean( false );
}
public boolean loadFrom( String f ) throws IOException {
DataInputStream s = new DataInputStream( BufferredInputStream(
FileInputStream( f ) ) );
boolean result = loadFrom( s );
s.close();
return result;
}
public boolean loadFrom( DataInputStream s ) throws IOException; {
// get int
value1 = s.readInt( );
if( class1 != null ) {
// do cleanup on current state
class1.finalize( );
// only if AppClass saved
if( s.readBoolean( ) ) {
// get empty instance
class1 = new AppClass();
// fill it in
class1.loadFrom(s);
else
class1 = null;
}
}
}

Se possível, prover uma classe utilitária que provenha à implementação de uma interface padrão. Isto permite qualquer classe que implemente a interface seja usada como uma classe utilitária. Isso aumenta o reuso.

--usando interfaces (modo preferencial) -//
class MyClass implements AnInterface {
private AnInterfaceImplementation implementation;
public MyClass() {
implementation = new AnInterfaceImplementation();
}
public void doIt( ) {
// implementação padrão para reuso
implementation.doIt();
}
}
--uso da implementação (se não existe nenhuma outra superclass) --
//
class MyClass implements AnInterface extends AnInterfaceImplementation
{
:
}
// uso do código
class Application {
public static void main(String[] args) {
AnInterface x = new MyClass();
:
x.doIt();
}
}

Definição -Considere diferenças entre atributos hiding e métodos overloading

Atributos nas subclasses com o mesmo nome dos atributos da superclasses, "escondem" os atributos existentes na superclasse. Métodos na subclasse com o mesma assinatura dos métodos existentes na superclasse sobrescrevem os métodos existentes na superclasse.

Exemplo:

package demo;
public class Base {
public int field1 = 1;
public int getField1( ) {
return field1;
}
}
--outro arquivo fonte-


Não use deste modo

package demo;
public class Derived extends Base {
public int field1 = 2;
public int getField1( ) {
return field1;
}
}
--outro arquivo fonte -import 
demo.*;
class Application {
public static void main( String arg[] ) {
Base b = new Base( );
Derived d = new Derived( );
// imprime: 1,2
System.out.println( b.field1 + "," + d.field1 );
// imprime: 1,2
System.out.println( b.getField1( ) + "," + d.getField1( ) );
b = d;
// imprime: 1,2
System.out.println( b.field1 + "," + d.field1 );
// imprime: 2,2
System.out.println( b.getField1( ) + "," + d.getField1( ) );
}
}
<source><![CDATA[
			</p>
			<p>	
				Diferente deste exemplo, atributos são normalmente declarados como private com métodos públicos 
				de acesso. Isto poderia resultar em resultados inesperados. 
				<br/>
<source><![CDATA[
package demo;
public class Base {
private int field1 = 1;
public int getField1( ) {
return field1;
}
}
--outro arquivo fonte--
package demo;
public class Derived extends Base {
private int field1 = 2;
public int getField1() {
return field1;
}
}
--outro arquivo fonte -import 
demo.*;
class Application {
public static void main(String arg[]) {
Base b = new Base();
Derived d = new Derived();
// erro de compilação
//System.out.println(b.field1 + "," + d.field1);
// imprime: 1,2
System.out.println(b.getField1() + "," + d.getField1());
b = d;
// erro de compilação
//System.out.println(b.field1 + "," + d.field1);
// imprime: 2,2
System.out.println(b.getField1() + "," + d.getField1());
}
}


Note: Dado apenas uma instancia de Derived, não existe forma através dessa instancia de acessar Base.field1.

Atenção -A referencia super é equivalente ao uso de casting com this

Dada a superclasse B e a subclasse D, uso de "super" em D é o mesmo que a expressão "((B)this)", mas deve usar o "super".

Exemplo:

class Base {
public int field1 = 1;
}
class Derived extends Base {
public int field1 = 2;
public void x() {
super.field1 = this.field1; (use assim) 
// prints: true 
System.out.println(((Base)this).field1 == this.field1);(Não 
use) 
} 
} 

Regra -Evite o uso de parâmetros em métodos que conflitem com atributos da classe

Isto evita confusão e ajuda a prevenir erros lógicos.

Exemplo:

package com.acme.dados;
public class MPC {
void method (int i, int j) {} // VIOLACAO
void j() {}
private int i = 0;
}

Reparar:

package com.acme.dados;
public class MPCFixed {
void method (int first, int second) {} // INDICADO
void j() {}
private int i = 0;
}

Construção de classe

Construtor

Regra -Sempre inicialize a superclasse e caso necessário os atributos

Para qualquer classe que tenha uma superclasse(que não seja Object), sempre será necessário explicitar a inicialização da superclasse. Atributos que precisam ser inicializados devem ser feito no construtor.

Isso auxilia o reuso de construtores complexos para construtores simples(com poucos ou nenhum argumento).

Exemplo:

class Person {
String name;
String address;
int age;
// construtor padrão
Person() {
// reuso de construtor
this( "--Unknown --", "--Unknown --", -1 );
}
// construtor
Person( String name, String address, int age ) {
name = name;
address = address;
age = age; 
} 
} 

class Employee extends Person {
int _id;
// construtor padrão
Employee() {
// reuso de construtor (não use)
this( "--Unknown --", "--Unknown --", -1, -1 );
--ou -// 
melhor forma (use essa)
super( );
id = -1;
}
Employee( String name, String address, int age, int id ) {
// explicite a inicialização da superclasse
super( name, address, age );
id = id;
}
}

Regra -Não inicialize atributos estáticos dentro do construtor

Atributos estáticos podem somente ser inicializados uma única vez na classe. Isto é feito quando a classe é carregada. Atribua um valor inicial para a declaração ou inclua um bloco estático caso seja necessário algum processo para obter o valor inicial(ex: um loop).

Exemplo:

class MyClass {
// inicialização estática
static int s = 10;
// inicialização dinâmica, implied = 0
int v;
// inicialização dinâmica
char c = ' ';
MyClass( ) {
// inicialização dinâmica
v = 10;
}
}
--ou -class 
MyClass {
// inicialização estática, valor = null
static int[] s;
// inicialização dinâmica, valor = 0
int v;
// inicialização dinâmica, valor = '
char c;
}

Definição -Minimize as funções providas pelos construtores

Construtores são chamados freqüentemente. Portanto eles devem ser eficientes. Use construtores para inicialização de construtores. Funções extensivas devem ser deixadas para ações realizadas por outros métodos que são explicitamente chamados após a construção.

Exemplo:

class File {
String name;
int mode;
:
public static final int INPUT = 1;
public static final int OUTPUT = 2;
public static final int INOUT = 3;
static final int CLOSED = 0;
// apenas seta o parâmetro, não abre o arquivo
public File( String newName ) {
name = newName;
mode = CLOSED;
}
// realizar fechamento
protected void finalize( ) {
close();
}
public boolean open( int newMode ) {
// limpa qualquer atividade anterior
close( );
mode = newMode;
// preenchimento para uma nova abertura
}
public boolean close( ) {
if(mode != CLOSED) {
mode = CLOSED;
}
}
}

Prover um construtor padrão private para classes utilitárias Classes utilitárias somente contem métodos e variáveis estáticas. Estas classes devem conter um construtor private para evitar que a classe possam ser instanciadas.

Exemplo:

package com.acme.util;
public class UCDC {
// VIOLACAO: implica no construtor padrão ser "public"
public static String s = "foo";
public static String getS() {
return s;
}
}


Reparar:

Declare explicitamente um construtor private padrão.

package com.acme.util;
public class UCDCFixed {
private UCDCFixed () {} // INDICADO
public static String s = "foo";
public static String getS() {
return s;
}
}

Encapsulamento e controle de acesso

Regra -Não mude a visibilidade de um método em uma classe derivada

Mudar a visibilidade de um método nos diferentes níveis hierárquicos de classes(subclasses) pode resultar em checagem de acesso inconsistente.

Somente é permitido em Java que subclasses mudem a visibilidades de métodos herdados (ex., private -protected -public) para uma visibilidade menos restrita (ex., public -protected -private).

Exemplo:

class Base {
private void foo() {
...
}
}
class Derived extends Base {
public void foo() {
...
}
}
class Application {
static void func() {
Derived d = new Derived(); 
Base b = d; 
// OK 
d.foo(); 
// erro de compilação
b.foo();
}
}

Definição -Maximize o uso de encapsulamento de atributos(private)

Crie todos os atributos como private e provenha métodos de acesso para eles. Isso permite uma maior flexibilidade para mudanças de implementação.

Exemplo:

class MyClass {
// data member
private MyType data;
public MyType getData( ) {
return data;
}
public void setData( MyType newData ){
data = newData;
}
}

Diferentes níveis de acesso podem ser conseguidos pela mudança de visibilidade nos tipos de acesso dos métodos.

class MyClass {
// data atributo
private MyType data;
// data atributo
private MyType data2;
public MyType getData( ) {
return data;
}
protected void setData ( MyType newData ){
data = newData;
}
public MyType getData2( ) {
return data2;
}
private void setData2( MyType newData2 ) {
data2 = newData2;
}
}

Aqui o valor do atributo data é somente de leitura para todas as classes, exceto as subclasses enquanto data2 é somente de leitura para todas as classes.

Quando implementar métodos modificadores que recebem diferentes tipos de parâmetros, use o setter padrão.

class MyClass {
// data member
private String data;
public MyType getData( ) {
return data;
}
protected void setData ( String newData ){
data = newData;
}
// use setter padrão
public void setData(int newData ) {
setData(new String(newData));
}
}

Definição -Nunca crie referencias diretas para os atributos da classe

Todos os acessos aos atributos de uma classe devem ser feitos através dos métodos acessores(setter e getter).

Definição -Criação de atributos abstratos

Concidere a criação de atributos de abstratos, especialmente em classes abstratas. Isso permite que implementações de atributos sejam mudadas nas subclasses.

Exemplo:

abstract class MyClass {
// get
public abstract MyType data( );
// set
public abstract void data( MyType x );
}
class MySubClass extends MyClass {
AnotherType data;
public MyType getData( ) {
return ( MyType ) data;
}
public void setData( MyType x ) {
data = ( AnotherType )x;
}
}

Definição -Minimize o tempo de vida de um objeto

Mantenha o tempo de vida de um objeto o mais curto possível. Coloque a declaração do atributo no inicio dos blocos aninhados. Se um operador new é usado, após o uso do objeto atribua null para ele.

Definição -Use com atenção a definição de visibilidade para um atributo

Java permite cinco tipos de visibilidade:

private

Somente métodos declarados na classe podem acessar esses atributos, esses atributos são encapsulados pelo uso do private, e devem ser acessados através de métodos públicos de acesso.

  • Use essa visibilidade para todos os atributos de uma classe.
  • Use essa visibilidade para todos os métodos de "apoio" de uma classe.


protected ( Cuidado com o uso )

Somente métodos declarados na classe, ou qualquer subclasse, ou qualquer classe existente no mesmo pacote poderão acessar.

--Default --

Somente métodos declarados na classe ou qualquer classe que esteja no mesmo pacote. O uso do default se faz pela ausência de qualquer keyword para especificar visibilidade.

public

Todas as classes podem acessar

Regra -Evite mais de dois níveis de aninhamento de classes

Aninhamento em mais de dois níveis podem ser difíceis de compreender.

Exemplo:

package com.acme.dados; 
public class LEVEL { 
class Level1 { 
class Level2 { 
class Level3 { // VIOLACAO 
private boolean _isClosed = false;
}
private int _count = 0;
} 
private int _size = 0;
}
private int _length = 0;
} 


Reparar:

Mova o código da classe aninhada para um arquivo em separado.

package com.acme.dados; 
public class LEVELFixed { 
class Level1 { 
class Level2 { 
private int _count = 0;
}
private int _size = 0;
} 
private int _length = 0; 
} 
Level3Fixed.java'
Segundo arquivo ': 
package com.acme.dados; 
class Level3Fixed { 
private boolean _isClosed = false; 
} 

Herança

Regra -Mova os códigos em comum para dentro de uma hierarquia

Reusar o máximo. Códigos comuns a classes do mesmo tipo devem ser colocados em uma superclasse e essa passar a ser pai das outras classes. Se necessário às subclasses podem realizar override dos métodos herdados.

Exemplo:

Contraste:

import java.util.Vector;
// de Integers
class IntCollection {
protected Vector elements;
// bubble sort
public void sort( ) {
int i, j, size = elements.size();
// para cada elemento
for( i = 0; i < size -1; i++ ) {
// comparação
for( j = i + 1; j < size; j++ ) {
Integer t1 = (Integer)elements.elementAt( i );
Integer t2 = (Integer)elements.elementAt( j );
//
if( t1.intValue() t2.intValue( ) ) {
elements.setElement( i, t2 );
elements.setElement( j, t1 );
}
}
}
}
// adiciona elementos
public void add( int x ) {
elements.addElement( new Integer( x ) );
}
}
// de Strings
class StringCollection extends Collection {
protected Vector elements;
// bubble sort
public void sort( ) {
int i, j, size = _elements.size( );
// for each element 
for( i = 0; i < size -1; i++ ) { 
// compare against all others 
for( j = i + 1; j < size; j++ ) { 
String t1 = (String)_elements.elementAt( i ); 
String t2 = (String)_elements.elementAt( j ); 
// check reorder needed 
if(t1.compareTo( t2 ) 0) { 
// swap elements 
elements.setElement( i, t2 ); 
elements.setElement( j, t1 ); 
} 
} 
} 
} 
// adiciona elemento 
public void add( int x ) { 
elements.addElement( x ); 
} 
} 

Regra -Mova código comum para dentro de métodos privados

Métodos comuns devem ser quebrados em métodos private ou mesmo protected.

Exemplo:

Compare:

import java.util.Vector; 
class List { 
private Vector elements; 
: 
// imprimir saída na stream 
public void print() { 
System.out.print("List("); 
for(int i = 0; i < elements.size(); i++) 
System.out.print((i == 0 ? "" : ", ") + 
elements.elementAt(i)); 
System.out.print(")"); 
} 
// imprimir erro na stream 
public void dump() { 
System.err.print("List("); 
for(int i = 0; i < elements.size(); i++) 
System.err.print((i == 0 ? "" : ", ") + 
elements.elementAt(i)); 
System.err.print(")"); 
} 
} 


com:

import java.util.Vector;
import java.io.PrintStream;
class List {
private Vector elements;
:
protected void dumpOn(PrintStream s) {
s.print("List(");
for(int i = 0; i < elements.size(); i++)
s.print((i == 0 ? "" : ", ") + elements.elementAt(i));
s.print(")");
}
// imprime a saída em uma stream
public void print() {
dumpOn(System.out);
}
// imprime erro em uma stream
public void dump() {
dumpOn(System.err);
}
}

Herança de métodos

Padrões e convenções para métodos

Regra -Chame método estático com operador de escopo

Para realizar chamada a métodos estáticos não instancie objetos.

Exemplo:

class MyClass {
// class method
public static void sfunc();
// instance method
public void func();
}
class Application {
void func( MyClass x ) {
// non-static method call
x.func();
// use essa chamada
MyClass.sfunc();
// não use essa chamada
x.sfunc();
}
}

Definição -Overload on type whenever it’s possible

Java permite a utitilzação de vários métodos com o mesmo nome, somente sendo necessário a troca de assinatura. Isso é chamado de overloading.

Example:

class MyClass {
:
public void someMethod( String arg ) {
// string specific processing
}
public void someMethod( Integer arg ) {
// integer specific processing
}
public void someMethod( Number arg ) {
// number specific processing
}
:
}

Tipo de retorno

Definição -Retorne um arrays de objeto com tipo

Não use mais de um tipo de retorno e não retorne null para as referencias de array. É preferível retornar sempre um array com tamanho zero.

Example:

class SomeClass {
:
public int[] someMethod( ) {
:
}
:
}

Gerenciando Exception

Regra -Previna seu programa de erros

Exceptions também reduzem a quantidade de checagem de código retornado para verificação de erros.

Nota: A clausula finally reduz código duplicado, como fechamento de arquivos. Considere:

import java.io.*;
class SomeClass {
public void doIt(String name)throws Exception,FileNotFoundException { 
FileInputStream fis;
// declaração de IOException
// e FileNotFoundException
fis = new FileInputStream(name);
:
}
}
--ou -public 
void doIt(String name) {
try {
FileInputStream fis;
fis = new FileInputStream(name);
:
}
catch(IOException ex) {
// gerencia exception aqui
}
}
}

Regra -Evite blocos 'catch' em corpo vazio

É sempre uma boa idéia inserir gerenciamento de erro dentro de cada bloco "catch".

Exemplo:

package com.acme.dados;
public class AECB {
public void method () {
try {
System.in.read ();
} catch (java.io.IOException e) {
// VIOLACAO
}
}
}


Reparar:

Adicionado gerenciamento de exception dentro do bloco "catch".

package com.acme.dados;
public class AECBFixed {
public void method () {
try {
System.in.read ();
} catch (java.io.IOException e) {
System.out.println("Descriptive error"); // INDICADO
}
}
}

Diversos

Definição -Evite o use de referencias nulas

Referencias em Java são inicializadas com null se não explicitado nenhum valor.

Exemplo:

import java.util.HashTable;
class SomeClass {
static HashTable dictionary;
int value;
:
public SomeClass(String key, int value) {
dictionary.put(key, (Object)new Integer(_value = value));
}
:
public void printKey(String key) {
:
System.out.println("Value of " + key + " is " +
(Integer)(dictionary.get(key)).intValue());
:
}
:
}

Será lançada uma NullPointerException caso não seja achada uma chave durante a utilização do get(). Uma alternativa é:

// :
public void printKey(String key) {
:
Integer i = _dictionary.get(key);
System.out.println("Value " + key + " is " + (i != null ?
i.intValue() "undefined");
:
}
// :

Regra -Minimize o uso de tipos primitivos

Sempre que possível, use uma classe equivalente para o tipo primitivo em questão. Por exemplo: Integer para int, Character para char, etc. Pois dessa forma você terá mais funções e poderão ser utilizados como objetos.

Atributos de uma classe devem sempre ser objetos ou classe de wrapper( Integer, Double, etc ).

Exemplo

class SomeClass { 
: 
void someMethod() { 
// array de ints 
int[] intArray = new int[10] 
// array de Integers 
Integer[] integerArray = new Integer[10]; 
// vector de Objects (regardless of name)
Vector integerVector = new Vector();
intArray[0] = 1;
// erro de compilação
intArray[1] = new Integer(1);
// erro de compilação
integerArray[1] = 1;
integerArray[1] = new Integer(1);
// erro de compilação
integerVector.addElement(1);
integerVector.addElement(new Integer(1));
integerVector.addElement(new Integer(1).toString());
}
:
}

Definição -Cuidado ao usar concatenação de Strings com tipos variados

Se um dos operandos do sinal (+) for uma String, então ambos precisam ser. Java automaticamente convertera o outro operador que não for String. O resultado dessa conversão pode ser definido. Use parêntesis para controlar essa definição. Veja os exemplos:

Exemplo:

:
String x;
// objeto de algum tipo
Object o = new Blivit(...);
// x é "33" : gerado como Integer(1 + 2).toString() + "3"
x = 1 + 2 + "3";
// x é "123": gerado como ("1" + Integer(2).toString()) + 
Integer(3).toString() 
x = "1" + 2 + 3; 
// x is "123": gerado como ("1" + Integer(2).toString()) + 
Character('3').toString() 
x = "1" + 2 + '3'; 
// x é "15" : gerado como "1" + Integer(2 + 3).toString()
x = "1" + (2 + 3);
// x é "23" : gerado como ("" + Integer(2).toString()) + "3"
x = "" + 2 + "3";
// erro de compilação, + não defindo para os referente tipos
x = o + 1;
// erro de compilação, + não defindo para os referente tipos
x = 1 + o;
// x é "Blivit(...)1" : gerado como o.toString() +
Integer(1).toString()
x = o.toString() + 1;
// x é "1Blivit(...)" : gerado como "1" + o.toString()
x = "1" + o;
:

Definição -Arrays podem ser irregulares

Java aceita array multidimensional, eles armazenam objetos do mesmo tipo, mas não precisa ter o mesmo tamanho.

Exemplo:

:
int[][] aai = new int[100][50];
--equivalente -int[][] 
aai = new int[100][];
// aai.length == 100
for(int temp = 0; temp < aai.length; temp++)
// aai[*].length == 50
aii[temp] = new int[50];
:


aii é regular. Mas a estrutura permite:

:
int[][] aai = new int[100][];
// aai.length == 100
for(int temp = 0; temp < aai.length; temp++)
// aai[0].length == 1
// aai[1].length == 2
// aai[2].length == 3
aii[temp] = new int[temp + 1];
:
// aai[99].length == 100


aii é irregular.

Isso significa que se você passar um argumento do tipo "int[][]" este não podera ser assumido como regular.

class SomeClass {
public static void initAII(int[][] aii) {
// check dimension 1
for(int i = 0; i < aii.length; i++)
// check each dimension 2
for(int j = 0; j < aii[i].length; j++)
aii[i][j] = i * j;
}
}

Regra -Usando JDBC sempre utilize a chamada ao método close() após utiliza-lo

Isso é uma boa pratica e alguns drivers requerem que isso seja feito, para auxiliar na "limpeza" dos recursos.

Exemplo

class Foo {
...
Connection conn = null;
Statement stmt = null
try {
conn = DriverManager.getConnection( url, user, pwd );
Statement stmt = con.createStatement( );
...
// sua lógica de negócio aqui
...
} catch (SQLException e) {
e.printStackTrace();
} finally {
// limpa todos os recursos usados no statement
stmt.close();
// limpa todos os recursos usados e fecha a sessão
conn.close();
}
}

Regra -Evite concatenação de String com « += »

Concatenação de String podem refletir em impactos na performance. Lembre String são objetos imutáveis, dessa forma, a concatenação resulta na criação de objetos temporários. Uma solução para isso é utilizar o java.lang.StringBuffer.

Regra -Evite o uso do operador de negação '!'mais do que 3 vezes dentro de um método

O operador de negação prejudica a legibilidade do código.

Exemplo:

package com.acme.dados;
public class DUN {
boolean method (boolean a, boolean b) { // VIOLACAO
if (!a)
return (!a && !b);
else
return !b;
}
}


Reparar:

Não use o operador de negação se possível

package com.acme.dados;
public class DUNFixed {
boolean method (boolean a, boolean b) {
if (a)
return !b;
else
return (! (a || b) );
}
}

Regra -Evite que atributos estáticos que não final tenham seu valor alterado durante a inicialização

Valores estáticos podem ser modificados por outros usuários da classe, entretanto um atributo estático pode com isso conter valor diferente ao esperado pelos usuários da classe.

Exemplo:

package com.acme.dados;
public class NFS {
static int max = 10;
int size = max; // VIOLACAO
}

Regra -Evite atribuições a parâmetros de métodos

Atribuições a parâmetros de métodos que são do tipo "referencia" podem proporcionar erro, pois altera o valor no método chamador.

Example.

package com.acme.dados;
class AFP {
void method (int[] a) {
a[0] = 0; // VIOLACAO 
} 
} 


Reparar

Criar uma varivel local e realizar a cópia de conteúdo.

package com.acme.dados;
class AFPFixed {
void method (int[] a) {
int[] copy = new int [a.length];
System.arraycopy (a, 0, copy, 0, a.length);
copy[0] = 0; // INDICADO
}
}

Definição -Classes que somente tenham métodos abstratos e campos do tipo 'static final' deve ser definida como 'interface'

Exemplo

package com.acme.dados;
abstract class ASFI { // VIOLACAO
abstract void method();
final static String ID = "final static string";
}


Reparar:

Substitua "abstract class" por "interface".

package com.acme.dados;
interface ASFIFixed { // INDICADO
void method();
String ID = "MISC_ASFI";
// Não precisa definir "final static", isto esta implícito
}

Regra -Evite chamar métodos que não sejam final, static ou private dentro do construtor

O objetivo do construtor é inicializar um objeto. Se o método puder ser acessado por uma subclasse, poderá ser feito um override, gerando um resultado não esperado.

Exemplo:

package com.acme.dados;
public class CTOR {
public CTOR () {
_size = readSize(); // VIOLACAO
}
public int readSize () {
return fis.read ();
}
private FileInputStream fis = new FileInputStream ("data.out");
private int _size;
}


Reparar:

Se o construtor necessita chamar um método na inicialização, faça esse método "final" ou "private". Ou crie um método "private void" para realizar a inicialização.

package com.acme.dados;
public class CTORFixed {
public CTORFixed () {
_size = readSize ();
}
private int readSize () { // INDICADO
return fis.read ();
}
private FileInputStream fis = new FileInputStream ("data.out");
private int _size;
}

Regra -Evite utilizar String.equals ('literal'), use 'literal'.equals (String)

Suponha que você tenha uma variável 'str'. Se você chamar str.equald("literal"), então você precisa primeiro ter certeza que a variável não esta null. Se você utiliza a chamada "literal".equals(str), você não precisa se preocupar em verificar se a variável esta null, isso torna o código mais conciso.

Exemplo:

package com.acme.dados;
public class ISEM {
public boolean isHello (String str) {
return (s != null && s.equals("Hello")); // VIOLACAO 
} 
} 


Reparar:

package com.acme.dados;
public class ISEMFixed {
public boolean isHello (String str) {
return "Hello".equals (str); // INDICADO
}
}

Performance

Regra -Evite usar a keyword 'new' quando criar objetos do tipo String para armazenar literais

Copiando um literal para dentro de um objeto String "gasta" tempo e é redundante

Exemplo:

package com.acme.dados;
class ACDO {
void method () {
System.out.println (_s);
}
private String _s = new String ("ACDO"); // VIOLACAO
}


Reparar:

package com.acme.dados;
class ACDOFixed {
void method () {
System.out.println (_s);
}
private String _s = "ACDO"; // INDICADO
}

Regra -Evite criação desnecessária de objetos para converter tipos primitivos em String

Java prove as classes de wrapping para tipos primitivos. Todas essas classes provém o método estático toString() para converter tipos primitivos em String. Mas essas classes fornecem métodos estáticos que evitam a criação desnecessária de objetos.

Exemplo:

package com.acme.dados;
public class AUTP {
String foobar (int x) {
return new Integer (x).toString (); // VIOLACAO 
} 
} 


Reparar:

package com.acme.br;
class AUTPFixed {
String foobar (int x) {
return Integer.toString (x); // INDICADO
}
}

Definição -Evite o uso de 'Date[]', use 'long[]'

O objeto Date contem muitos campos, e com isso utiliza muito espaço. Caso seja necessário utilizar um array de objetos Date, substitua pelo uso de um array de long, onde somente serão armazenados os valores "long" que representam as datas.

Exemplo:

package com.acme.dados;
import java.util.Date;
public class DUD {
Date d[]; // VIOLACAO
}

Reparar:

O uso de um array do tipo long e mais eficiente do que um array do tipo Date.

package com.acme.dados;
import java.util.Date;
public class DUD {
long d[]; // INDICADO
}

Regra -Evitar 'static' collections

Objetos que representem coleções estáticas(Vector, Hashtable, etc) podem armazenar vários outros objetos, fazendo com que possa ocorrer memory leaks. Se você coloca vários pequenos objetos em uma coleção estática, esses objetos serão referenciados por essa coleção por toda a "vida" do programa se você esquecer de remove-los da coleção quando tiver terminado o uso com esses objetos. Se você tiver removido todas as referencias para esses pequenos objetos, poderá ser difícil ver que ainda existe referencia feita pela coleção.

Exemplo

package com.acme.dados;
import java.util.Vector;
public class STV {
public static Vector vector = new Vector (); // VIOLACAO
void addToVector () {
Object o = new Object ();
vector.add (o); // este objeto temporariamente não será liberado 
} 
} 


Reparar:

Se o uso de variveis estaticas é necessário, informe o tamanho maximo e tenha certeza que não excedera esse tamanho.

package com.acme.dados;
import java.util.Vector;
public class STVFixed {
public static void addToVector () {
// verifica o tamanho máximo do Vector antes de chamar 'add()'.
if (vector.size() < MAX_SIZE) { // INDICADO
Object o = new Object ();
vector.add(o);
}
else {
System.err.println("vector MAX_SIZE excedido.");
}
}
public static Vector vector = new Vector (5); // INDICADO
public static final int MAX_SIZE = 100;
}

Regra -Use abreviações de operadores

Alguns compiladores rodam mais rápido dessa forma, além de ser mais conciso o código.

Exemplo:

package com.acme.dados;
public class AAS {
void method () {
int i = 0;
i = i -1; // VIOLACAO
}
}


Reparar:

package com.acme.dados;
public class AAS {
void method () {
int i = 0;
i -= 1;
}
}

Definição -Evite chamar métodos dentro do statement de condição de um loop

A menos que o compilador otimize-o, a condição do loop será calculada para cada iteração sobre o loop. Se o valor de condição não sofre mudança, ele será executado mais rápido do que a chamada de um método fora do loop.

Exemplo:

package com.acme.dados;
import java.util.Vector;
class CEL {
void method (Vector vector) {
for (int i = 0; i < vector.size (); i++) // VIOLACAO
{
System.out.println(i);
}
}
}


Reparar:

Se o método retorna um valor que não será alterado durante o loop, então armazene esse valor em uma variável temporária antes do loop.

package com.acme.dados;
class CELFixed {
void method (Vector vector) {
int size = vector.size ();
for (int i = 0; i < size; i++) // INDICADO
{
System.out.println(i);
}
}
}

Regra -Uso do operador condicional 'if (cond) return; else return;'

O operador condicional prover uma simples expressão que executa um ou outro statement, baseado em uma expressão boleana. Este resultado é uma expressão mais compacta.

Exemplo

package com.acme.dados;
public class IF {
public int method (boolean isDone) {
if (isDone) // VIOLACAO
return 0;
else
return 10;
}
}


Reparar:

Substitua o bloco 'if-else'por um statement usando um operador condicional package com.acme.dados;

public class IFFixed {
public int method (boolean isDone) {
return isDone ? 0 : 10;
}
}

Regra -Uso do operador condicional 'if (cond) a = b; else a = c;'

O operador condicional prover uma simples expressão que executa um ou outro statement, baseado em uma expressão boleana. Este resultado é uma expressão mais compacta.

Exemplo:

package com.acme.dados;
public class IFAS {
void method(boolean isTrue) {
if (isTrue) // VIOLACAO
_value = 0;
else
_value = 1;
}
private int _value = 0;
}


Reparar:

Substitua o bloco 'if-else'por um statement usando um operador condicional

package examples.Regras.opt;
public class IFASFixed {
void method(boolean isTrue) {
_value = (isTrue ? 0 : 1); // INDICADO
}
private int _value = 0;
}

Regra -Use 'charAt()'ao invés de 'startsWith()'para comparação de um caracter

O uso de startsWith() executa várias funções para preparar a comparação do prefixo com outra string, as quais se tornariam desnecessárias quando apenas se que comparar um caractere com outro.

Exemplo:

package com.acme.dados;
public class PCTS {
private void method(String s) {
if (s.startsWith("a")) // VIOLACAO
System.out.println("starts with a.");
}
}


Reparar:

package examples.Regras.opt;
public class PCTSFixed {
private void method(String s) {
if (s.length () > 0 && s.charAt(0) == 'a') // INDICADO
System.out.println("starts with a.");
}
}

Definição -Evite chamadas de métodos 'synchronized' em um loop

Métodos "synchronized" são "caros", a invocação desses métodos dentro de um loop não é recomendada.

Exemplo:

package com.acme.dados;
public class SYN {
public synchronized void method () {
}
private void test () {
for (int i = 0; i < 100; i++) {
method (); // VIOLACAO 
} 
} 
} 

Definição -Coloque blocos 'try/catch' fora dos loops

O uso de blocos "try/catch" dentro de loops pode representar perda de performance do código executado.

Exemplo:

package com.acme.dados;
import java.io.FileInputStream;
public class TRY {
void method (FileInputStream fis) {
for (int i = 0; i < size; i++) {
try { // VIOLACAO
_sum += fis.read ();
} catch (Exception e) {}
}
}
private int _sum;
}


Reparar:

Coloque o bloco "try/catch" fora do loop.

package com.acme.dados;
import java.io.FileInputStream;
public class TRY {
void method (FileInputStream fis) {
try { // INDICADO
for (int i = 0; i < size; i++) {
_sum += fis.read ();
}
} catch (Exception e) {}
}
}

Regra -Evite desnecessários casting

Todas as classes são direta ou indiretamente herança da classe Object. Também, quaisquer subclasses são implicitamente do mesmo tipo da sua superclasses e das interfaces que ela implementa. Entretanto, operações de cast para superclasses ou interfaces implementadas são desnecessárias.

Exemplo:

package com.acme.dados;
class UNC {
String _id = "UNC";
}
class Dog extends UNC {
void method () {
Dog dog = new Dog (); 
UNC animal = (UNC)dog; // VIOLACAO 
Object o = (Object)dog; // VIOLACAO 
} 
} 


Reparar:

Remova todas os cast's desnecessários para as classes pai ou interfaces implementadas. package com.acme.dados;

class DogFixed extends UNC {
void method () {
Dog dog = new Dog();
UNC animal = dog; // INDICADO
Object o = dog; // INDICADO
}
}

Regra -Use variáveis 'stack'sempre que possível

Quando varáveis são acessadas freqüentemente, considere de onde elas são acessadas. É uma variável estática, local, ou a instancia de objeto? Variáveis estáticas e instancias, custam duas ou três vezes mais tempo para serem acessadas do que variáveis locais.

Exemplo:

package com.acme.dados;
public class USV {
void addSum (int[] values) {
for (int i=0; i < value.length; i++)
_sum += value[i]; // VIOLACAO.
}
private int _sum;
}


Reparar:

Se possivel, use variaveis locais quando forem acessadas frequentemente. Por exemplo você poderia usar uma variavel local temporaria como:

package com.acme.dados;
public class USVFixed {
void addSum (int[] values) {
int sum = _sum; // variavel local temporaria.
for (int i=0; i < value.length; i++)
sum += value[i];
_sum = sum;
}
private int _sum;
}

Feedback

Por favor, dê a sua opinião a respeito do conteúdo apresentado. Correções, sugestões ou qualquer outra informação relevante é de suma importância para nós e será muito bem vinda.

Contato: owner@hotwork.dev.java.net