Dúvida com passagem de parâmetros em métodos set

9 respostas
rylphs

Olá pessoal,

Sou novo no java, então se eu perguntar algo muito óbvio me perdoem.
Bem, pelo que pesquisei, no java a passagem de parâmetros se dá por referência, né? Isso não pode ser perigoso?

Em uma classe, tenho algo do tipo:

void setData(Calendar data){ this.data = data; }

Diagamos que ao utilizar o método, eu passe como parâmetro um objeto Calendar de outra classe. Isso traria efeitos indesejáveis, porque, depois do método, qualquer alteração em uma das datas, também ocasionaria uma mudança na outra. Estou certo?

Como não quero isso, estou codificando o meu set da seguinte maneira:

void setData(Calendar data){ this.data = (Calendar) data.clone(); }

Essa seria a melhor maneira de fazer isso? Existe algum padrão? Porque eu acho que atribuir um objeto diretamente cria uma vinculação desnecessária e até perigosa.

Bem, espero ter sido claro. Obrigado!

9 Respostas

T

rylphs:
Olá pessoal,

Sou novo no java, então se eu perguntar algo muito óbvio me perdoem.
Bem, pelo que pesquisei, no java a passagem de parâmetros se dá por referência, né? Isso não pode ser perigoso?

Em uma classe, tenho algo do tipo:

void setData(Calendar data){ this.data = data; }

Diagamos que ao utilizar o método, eu passe como parâmetro um objeto Calendar de outra classe. Isso traria efeitos indesejáveis, porque, depois do método, qualquer alteração em uma das datas, também ocasionaria uma mudança na outra. Estou certo?

Como não quero isso, estou codificando o meu set da seguinte maneira:

void setData(Calendar data){ this.data = (Calendar) data.clone(); }

Essa seria a melhor maneira de fazer isso? Existe algum padrão? Porque eu acho que atribuir um objeto diretamente cria uma vinculação desnecessária e até perigosa.

Bem, espero ter sido claro. Obrigado!

Interessante você ter notado isso.

Isso indica o seguinte problema de criar setters automaticamente:

  • Você está usando objetos mutáveis (como Calendar em vez de Date), e para eliminar eventuais efeitos colaterais, você cria uma cópia privada deles, o que é recomendável.

Mas se pudesse usar objetos imutáveis, então você não teria o tal problema e poderia usar o “setter” automático (ou seja, aquele criado com a receita de bolo, sem pensamento nenhum.)

rylphs

Então o que eu estou fazendo é o melhor a se fazer?

Lavieri

o que ele quis dizer é que usar um Date, que é imutavel, no lugar do Calendar, não traria esse problema

private Date data;

Date getData() {
   return data;
}

Calendar getCalendar() {
   Calendar calendar = Calendar.getInstance();
   calendar.setTime(data);
   return calendar;
}

void setData(Calendar data){   
    this.data = data.getTime();
}

void setData(Date data) {
    this.data = data;
}
rylphs

Mas e quando não tiver como eu usar um objeto imutável?

Um amigo meu me falou que usar clones em gets e sets é errado. Mas se eu tenho por exemplo:

public Class A{
}

public Class B{
   private A atributoPrivado;

   public A getAtributoPrivado(){
       return atributoPrivado;
   }
}

Se em um método main, por exemplo, eu chamo:

b = new B();
a = B.getAtributoPrivado();

O atributo deixaria de ser privado, porque agora eu posso alterar ele diretamente. Então o que eu quero saber é se usar cópias, nesse caso seria melhor.

peczenyj

Se vc quer garantir a imutabilidade do seu objeto e possui um atributo Calendar, vc pode seguir com gets e sets - lembrando que basta vc criar copias de segurança

public Calendar getData() { Calendar copia = Calendar.getInstance(); copia.setTimeInMillis(this.data.getTimeInMillis()); return copia; }

note que o setData deve sofrer operação semelhante.

rylphs

Valeu galera, pelo esclarecimento.

C

Gente, tenho uma dúvida quanto a isto. É recomendado (por motivos de segurança) criar getters, setters e outros metodos que retornam com o metodo clone() ? Se não, em quais situações isso é recomendado. Outra coisa, não entendi direito a diferença entre Date e Calendar nessa situação, já que nas duas é possível alterar atributos, como data, hora… Obrigado.

D

Pessoal estou com um problema com Calendar, sem uma possivel solução, tentei varias coisas mas até agora nada, se puderem me ajudar agradeço muito, tenho o seuginte codigo:

public java.util.Calendar calendar;
public java.util.Date data;
public String str_date;

    private void tbPacienteLinhaSelecionada(JTable tb) {
        desabilitarCampos();
        if (tb.getSelectedRow() != -1) {
            txtNome.setText(pacientes.get(tb.getSelectedRow()).getNome());
            txtBairro.setText(pacientes.get(tb.getSelectedRow()).getBairro());
            txtCEP.setText((pacientes.get(tb.getSelectedRow()).getCep()).toString());
            txtCelular.setText(pacientes.get(tb.getSelectedRow()).getCelular().toString());
            txtCidade.setText(pacientes.get(tb.getSelectedRow()).getCidade());
            txtComercial.setText(pacientes.get(tb.getSelectedRow()).getComercial().toString());
            txtComplemento.setText(pacientes.get(tb.getSelectedRow()).getComplemento());
            //Calendar Beg
            str_date = pacientes.get(tb.getSelectedRow()).getData_nascimento().toString().trim();
            try {
                String dataEnv = str_date.split(" ")[0]; // pega a data do banco em YYYY/MM/DD HH:mm:SS e pega só a data.
                System.out.println("dataEnv: " + dataEnv.toString());
                calen = Calendar.getInstance(Locale.ENGLISH); // instancia um calendar...
                int y = Integer.parseInt(dataEnv.split("-")[0]);
                int m = Integer.parseInt(dataEnv.split("-")[1]);
                int d = Integer.parseInt(dataEnv.split("-")[2]);
                //calen.set(Integer.parseInt(dataEnv.split("-")[0]), Integer.parseInt(dataEnv.split("-")[1]) - 1, Integer.parseInt(dataEnv.split("-")[2])); // inverte a data para DD/MM/YYYY e seta no calendar
                calen.set(y, m, d);
                cptNascimento.setSelectedDate(calen); // Seta o combochooser para o calendar.
                System.out.println("cptNascimento: " + cptNascimento.getText());
                System.out.println(Integer.parseInt(dataEnv.split("-")[0]) + Integer.parseInt(dataEnv.split("-")[1]) - 1 + Integer.parseInt(dataEnv.split("-")[2]));
            } catch (Exception e) {
                e.printStackTrace();
            }
            txtEndereco.setText(pacientes.get(tb.getSelectedRow()).getEndereco());
            txtEstado.setText(pacientes.get(tb.getSelectedRow()).getEstado());
            txtNumero.setText(pacientes.get(tb.getSelectedRow()).getNumero().toString());
            txtRG.setText(pacientes.get(tb.getSelectedRow()).getRG());
            txtCPF.setText(pacientes.get(tb.getSelectedRow()).getCPF().toString());
            txtTelefone.setText(pacientes.get(tb.getSelectedRow()).getTelefone().toString());
            cmbEstadoCivil.setSelectedItem(pacientes.get(tb.getSelectedRow()).getEstado_civil());
            cmbSexo.setSelectedItem(pacientes.get(tb.getSelectedRow()).getSexo());
            txtFoto.setText(pacientes.get(tb.getSelectedRow()).getFoto());
            Image img = new ImageIcon(txtFoto.getText()).getImage().getScaledInstance(100, 120, java.awt.Image.SCALE_AREA_AVERAGING);
            labelFoto.setIcon(new ImageIcon(img));
        } else {
            limparCampos();
        }
    }

Então eu acesso uma base de dados que jah tem alguns cadastros, um deles é 1988-10-01 00:00:00, mas a data no componente calendar nunca muda, fica sempre a data atual do sistema, como nessa tela aki…

Estou usando o componente DateChooserCombo… mas infelizmente estou tendo esses problemas, alguem pdoe me ajudar?

abraços…

D

Pessoal descobri o que era o problema, em um dos meus metodos nessa classe eu coloquei isso:

cptNascimento.setEnabled(false);

por isso q nao alterava, se for pra fazer isso tem qeu setar os valores e depois desabilitar hehehe

abraços a todos…

Criado 9 de abril de 2009
Ultima resposta 30 de out. de 2009
Respostas 9
Participantes 6