Dúvidas na inicialização de arrays para não gerar Exception in thread "main" java.lang.NullPointerEx

Meu nome é Cesar e estou com dificuldades na utilização de arrays para não gerar Exception in thread “main” java.lang.NullPointerEx.

Eu conheço o significado do erro, que indica que o objto está apontando para null. Por isso vc mostrar um exemplo simples para ver se alguém pode me auxiliar:

  1. Criei 3 classes (Empresa, Funcionario e Empresa Teste)
  2. Classe Funcionario (determinei apenas alguns atributos)

public class Funcionario {
String nome;//nome do funcionário
int rg;//nº do rg do funcionário
}

  1. Classe Empresa(Apresenta alguns atributos. Um deles é o atributo da classe Funcionario)

public class Empresa {
public static int contador=0;
String nomeDaEmpresa=“IaC”;
int cnpj;//nº do cnpj da empresa
Funcionario [] func=new Funcionario[10];

void adicionaFuncionario(){
this.func[contador].nome=“Fernando”;
this.func[contador].rg=1234;
}//fim do método adicionaFuncionario()

}//fim da classe empresa

  1. Classe EmpresaTeste (serve para testar o aplicativo)

public class EmpresaTeste {

public static void main(String args[]){
Empresa empresa=new Empresa();
System.out.println("Adicione um funcionário");
empresa.adicionaFuncionario();
}//fim do método main()

}//fim a classe EmpresaTeste

  1. Quando eu executo a classe EmpresaTeste ocorre o seguinte erro:

init:
deps-jar:
compile-single:
run-single:
Adicione um funcionário
Exception in thread “main” java.lang.NullPointerException
at Empresa.adicionaFuncionario(Empresa.java:23)
at EmpresaTeste.main(EmpresaTeste.java:19)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)

  1. Eu sei que o erro é apresentado na seguinte parte da classe Empresa:
    this.func[contador].nome=“Fernando”;

Gostaria de saber o que devo fazer para não ocorrer mais esse erro?

Obrigado pela Atenção
César

O problema é que você apenas criou um array de funcionários:

Funcionario [] func=new Funcionario[10];

Mas você não tem nenhuma instância da classe Funcionário, você teria que fazer + - assim:

void adicionaFuncionario() { this.func[contador] = new Funcionario(); // cria uma instância de Funcionário // agora você pode atribuir sem erro this.func[contador].nome="Fernando"; this.func[contador].rg=1234; }//fim do método adicionaFuncionario()

Só uma observação, você acessar as variáveis de instância diretamente de outra classe não é uma boa prática de OO, tais variáveis deveriam ser private (encapsulamento), então você forneceria métodos get e set…

Qualquer dúvida posta ai de novo…

Como faço pra apagar aki?? deu um probema na hora de postar…

erro…

Olá César! Bem vindo ao GUJ!
O problema é bem simples e corriqueiro na vida de quem tá começando em Java, portanto, não se preocupe, ok :thumbup: ?
Vamos rever sua classe Empresa:

public class Empresa {
	public static int contador = 0;
	String nomeDaEmpresa = "IaC";
	int cnpj;// nº do cnpj da empresa
	Funcionario[] func = new Funcionario[10];

	void adicionaFuncionario() {
		this.func[contador].nome = "Fernando";
		this.func[contador].rg = 1234;
	}// fim do método adicionaFuncionario()

}// fim da classe empresa

Essa sua classe tem um campo do tipo Funcionario[], ou seja, um campo que é um array de objetos Funcionario.
Quando vc instancia um Funcionario, e java executa a seguinte linha de código

	Funcionario[] func = new Funcionario[10];

o campo func será então um array de Funcionario com 10 posições. O que talvez voce não saiba, é que quando criamos um array da forma como vc criou:

	<uma_classe_qualquer>[] meuArray = new <uma_classe_qualquer>[n];

O Java cria um array apto a armazenar até n elementos do tipo <uma_classe_qualquer>, só que em cada uma desses posições, o Java atribui inicialmente o valor null.
Daí vem o seu NullPointerException, pois no main da classe EmpresaTeste, vc faz

Empresa empresa=new Empresa();

O que faz com que o campo func do objeto empresa referencie um array de Funcionario com 10 posições nulas.
Em seguida, vc faz

empresa.adicionaFuncionario(); 

O que faz a primeira linha desse método? Olhe só:

	void adicionaFuncionario() {
		this.func[contador].nome = "Fernando";
		...

contador neste momento vale 0, certo? Então, até o java vai avaliar aquela primeira linha do adicionaFuncionario. Ele vai avaliando da esquerda para a direita. O trecho this.func[contador] representa a primeira posição daquele array guardado pelo campo func, certo? Mas, o que tem mesmo naquele campo? Ali temos um null, pois quando func foi iniciado, foi atribuido null a todas as suas 10 posições.
Voltando, agora que o Java analisou o trecho this.func[contador], ele vai continuar analisando a linha, que agora, para o java, será algo assim

null.nome = "Fernando";

Opa! O Java vai tentar acessar um campo chamado nome a partir de null!!! Aí, não tem jeito… é NullPointerException na cabeça!!!
Sacou o que aconteceu?
O método inserirFuncionario não está bem escrito, mas tudo bem, pois como vc disse, vc está começando, e esses problemas são normais e digo até que são essenciais para o aprendizado.
Vou te dar uma sugestão: Vc não tem uma classe que representa um funcionário e outra classe que representa uma empresa? Porque então misturar os conceitos? O que vc acha de a sua classe EmpresaTeste se encarregar de “criar” um Funcionario e então mandar este Funcionário recem-criado para ser inserido dentro da Empresa? O que me diz?
Pense nisso, e tente re-escrever suas classes, ok?
Qq coisa, pergunte mais!
E mais uma vez, bem vindo ao GUJ!

Caro Diego 2006,
fiz a modificação que vc me sugeriu, mas ainda continuou apresentando o mesmo erro. Há alguma modificação que vc esqueceu de comentar?
Obrigado pela atenção
Caio

Caro Mantu,
apresentei essa dúvida para tentar esclarecer melhor os conceitos do java um pouco melhor. Vou seguir também teu conselho e reescrever o código com outra concepção, embora ainda esteja procurando uma solulção para essa questão apresentada.
atenciosamente
Caio

Ué! Mas vc conseguiu ver onde tá o problema?

Caro Mantu,

tentei seguir sua idéia e ela deu certo em parte. Vou mostrar o que eu fiz:

  1. Continuo com as mesmas 3 classes
  2. A classe Funcionario

public class Funcionario {
String nome;//nome do funcionário
int rg;//nº do rg do funcionário

  1. A clase Empresa

public class Empresa {
public static int contador=0;
String nomeDaEmpresa=“IaC”;
int cnpj;//nº do cnpj da empresa
Funcionario [] func=new Funcionario[10];

void adicionaFuncionario(Funcionario func){
this.func[contador]=func;
contador++;
//this.func[contador].nome=“Fernando”;
//this.func[contador].rg=1234;
}
}

  1. A classe empresaTeste

public class EmpresaTeste {

public static void main(String args[]){
Empresa empresa=new Empresa();
System.out.println("Adicione um funcionário");
Funcionario func=new Funcionario();
func.nome="caio";
func.rg=1234;    
empresa.adicionaFuncionario(func);
func.nome="cesar";
func.rg=1234;
empresa.adicionaFuncionario(func);
}//fim do método main()

}

Nesse caso o erro desapareceu, mas por outro lado não estou conseguindo criar array que apresente os dados cadastrais diferentes. Ou seja: func[1].nome=“caio” e func[2].nome=“cesar”. Na verdade os dois arrays estão todos apontando para o objeto func[1].nome=“cesar” e func[2].nome=“cesar”. Gostaria de saber se há alguma maneira de fazer com que func[1].nome e func[2].nome aponte para posições diferentes: Ou melhor que os dados (nome e rg) sejam distintos em cada um?
PS: Sei que ao mandar essa informação com objetos diferentes eu resolveria meu problema. Por exemplo func.nome e func2.nome.

Obrigado pela atenção de todos, consegui solucionar o problema graças as dicas de vcs.
atenciosamente
Caio

cchc,

    Velho usa a tag code por favor.
     E sobre suas classes o que acontece é q vc cria uma referencia pra todos os objetos. humm deixa eu ser mais claro um objeto não muda de referencia quando vc passa por parametro ao metodo. Vc faz isso

Funcionario a = new Funcionario(); a.nome = "caio"; a.rg=1234; //Aqui vc add o funcionario empresa.adicionaFuncionario(a); //aqui vc modifica os valores do objeto acima que agora deixa de ser caio e passa a ser cesar a.nome = "cesar"; a.rg=1234; //aqui vc salva empresa.adicionaFuncionario(a); //Nas duas posiçoes do array vc tme o MESMO objeto =) //Solução cria um novo objeto (uma nova instancia) Funcionario b = new Funcionario(); b.nome = "jose"; b.rg = 213; empresa.adicionaFuncionario(b);

Pronto tneta ae.

Precisando é so postar.