se vc olhar direito, não existe nenhuma variável chamada func no metodo main… func é atributo de Empresa e pra fazer o que vc quer, vc deve passar a.func[1] na linha 16
Talvez o pior erro foi não perceber que não existia a variável dentro do método main.
Mas acho que só entendi parcialmente.
Giulliano então, mas a variável que eu estava passando era um Objeto do tipo Funcionario, só que não estava declarado dentro do método main, como já dito.
E o correto seria a.adiciona pelo fato do mátodo adiciona estar declarado na classe Empresa, e a é um Objeto de Empresa.
Quanto a variável estar vazia acho que não era o caso, porque nas linhas anteriores eu tinha setado os valores de cada atributo da classe Funcionario. É ISSO MESMO?
RafaelVS É, do jeito que você disse compilou o programa, mais ainda sim continuou o erro: java.lang.NullPointerException
PQ?
Outro ponto, não quero apenas adicionar o valor de uma variável na classe Empresa, quero adicionar Objetos Empresa de Objetos Funcionario.
O que devo mudar então? Essa parte eu não entendi.
Pelo fato de:
func.nome
func.depto
func.sal
Serem o valor de cada atributo de Funcionario, pensei que apenas o Objeto func, seria o correto.
Valeu
Os cara aqui são fera mesmo, acho que nem tinha clicado “enviar” a msg e já tinha 3 respostas.
Um dia chego lá.
Oi, eu não prestei atenção na sua pergunta direito… achei que o único problema era que não estava compilando, por isso, só respondi a esse problema…
Está dando NullPointerException pelo seguinte motivo:
Quando vc faz:
Empresa a = new Empresa();
O atributo func de Empresa é criado com dois valores null.
Então, quando vc tenta fazer func[i].nome na classe mainEmpresa, o valor de func[0] é null … e ele tenta fazer algo como null.nome … por isso dá NullPointerException… Para funcionar, você deveria fazer o seguinte:
só para vc enteder o que eu quis dizer…não que o modo ÚNICO de se fazer seja esse…
três classes FUNCIONARIO / EMPRESA / MAINEMPRESA
package funcionario;
public class Funcionario {
public String nome;
public String depto;
public int sal;
public String getDepto() {
return depto;
}
public void setDepto(String depto) {
this.depto = depto;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public int getSal() {
return sal;
}
public void setSal(int sal) {
this.sal = sal;
}
}
package funcionario;
class MainEmpresa{
public static void main (String args[]){
Empresa a = new Empresa();
Funcionario f = new Funcionario();
f.setNome("Rafael");
a.adiciona(f);
a.imprime();
}
}
package funcionario;
class Empresa{
String nome, cnpj;
Funcionario func[] = new Funcionario[2];
int i = 0;
void adiciona (Funcionario f){
this.func[i] = f;
i++;
}
void imprime (){
System.out.println ("Nome Empresa: " +nome+ "CNPJ Empresa: " +cnpj);
}
}
Se você rodar o meu código ele compila e roda…porém imprime null…isso é pq vc não esta pegando o valor no lugar certo…
Claro que, mais uma vez, o exemplo que eu dei foi só pra atender a sua pergunta.
Pois seu código tem vários defeitos, a saber alguns deles:
[list]
Você está construindo sempre um array de tamanho 2… se você tentar adicionar um terceiro funcionário terá um erro como ArrayIndexOutOfBoundException.
Você está acessando as variáveis diretamente, ao invés de através de métodos de acesso.
Você está colocando os colchetes após o nome do atributo ao invés de após o nome do tipo (isso é bem subjetivo… ambas a formas estão corretas, mas li bastantes recomendações para colocar os colchetes após o tipo para ficar mais legível).
Você está acessando valores null (como expliquei anteriormente, devido à instanciação do array de Funcionarios).
Você estava tentando adicionar um funcionário que já estava adicionado (pois vc estava passando o funcionário na posição 1 do array ao método adiciona, o que iria colocar o objeto da posição 1 na posição 0 - já que era a primeira vez que vc estava chamando o método adiciona e, inicialmente, o valor do atributo i da classe Empresa é 0)
[/list]
[code]class mainEmpresa{
public static void main (String args[]){
Empresa a = new Empresa();
a.nome = “IBTA”;
a.cnpj = “123456789”;
for (int i=0; i<a.func.length; i++){ //faltava esse for, cada variável do tipo
a.func[i] = new Funcionario(); //funcionario não estava referenciando nenhum Objeto. CERTO?
} //com isso acabou o erro NullPointer Exception
int i = 0;
a.func[i].nome = "Rafael";
a.func[i].depto = "Java";
a.func[i].sal = 1500;
i++;
a.func[i].nome = "Ana";
a.func[i].depto = "C++";
a.func[i].sal = 1000;
a.adiciona(a.func[0]); //entendi aqui que o método adiciona da classe Empresa
//já está dizendo que é p/ adicionar na primeira posição,
a.imprime(); //mas se eu deixar comente a.func o programa não compila
a.func[0].imprimir();
}
}[/code]
Agora funcionou!
Giulliano, a linha package funcionario; eu nunca vi.
Mas serve para você importar os atributos da classe Funcionario e poder utilizar dentro de qualquer classe? PORQUE funcionario e não Funcionario
Se é que é isso mesmo.
RafaelVS, sobre suas observações:
[list]1. Verdade, não tinha me ligado nisso.
2. Métodos de acesso que você diz são os convencionais get e set, certo?
3. Já arrumei dentro das outras classes.
4. Faltava criar a referência que cada variável ia fazer p/ os Objetos, certo? Essa linha corrigiu o erro:
for (int i=0; i<a.func.length; i++){
a.func[i] = new Funcionario();
}
5. Esse caso entendi o que você disse, mas não consegui arrumar, veja que comentei no trecho do código aí em cima.[/list]
O problema principal no seu código ocorre quando você tenta acessar algum campo de um objeto Funcionariosupostamente inserido no vetor func da classe Empresa.
Vamos analisar:
Quando executamos a linha
Empresa a = new Empresa();
Temos na variável a um objeto do tipo Empresa com o seguinte estado (Quando digo estado, me refiro aos valores de cada campo do objeto em um determinado momento):
[quote]nome = null
cnpj = null
func = [null, null]
i = 0[/quote]
Nas linhas seguintes, legal, tudo bem, você atribui valores para os campos nome e cnpj, deixando o estado de a assim:
[quote]nome = “IBTA”
cnpj = “123456789”
func = [null, null]
i = 0[/quote]
Porém, pouco mais adiante, você tenta atribuir o valor “Rafael” ao campo nome de um objeto Funcionario - suuuupostameeente existente - na posição inicial daquele campo chamado func, a partir da variável a (Que é do tipo Empresa):
a.func[i].nome = "Rafael";
Intuitivamente, parece estar tudo certo. Mas tem um porém… como é mesmo que estava o estado do objeto Empresa referenciado pela variável a? Veja só:
[quote]nome = “IBTA”
cnpj = “123456789”
func = [null, null]
i = 0[/quote]
Aí eu te pergunto: O que é que temos na posição 0 do vetor func? Temos ali, por acaso, um objeto do tipo Funcionario? Não, né? Temos é um belo e gordo null. O null é uma variável (referência, na verdade) especial que não referencia nenhum objeto, ou seja, sua referência é nula.
Em Java, quando utilizamos o caractere ponto (".") à frente de uma variável, quer dizer que estamos tentando acessar um membro do objeto que está sendo referenciado pela variável em questão. Por exemplo, imagine a seguinte classe:
public class Cao{
public int idade = 0;
public void brincar(){
// Algum código aqui...
}
}
Agora, vamos instanciar um objeto da classe Cao e referenciá-lo com uma variável chamada “totoh”:
Cao totoh = new Cao();
Se quisermos saber a idade do nosso cãozinho, teremos que recuperar essa informação a partir da variável totoh. Para isso, vamos utilizar o “.” à frente da variável totoh para termos acesso aos membros da classe Cao. No nosso caso, ficaria assim:
int age = totoh.idade;
Da mesma forma, se quisermos mandar nosso cão brincar, temos que acessar o método brincar utilizando o “.” na variável totoh:
totoh.brincar();
Perceba que o Java utiliza o caractere “.” para acessar algum membro (método ou campo, por exemplo) do objeto (Um pouco mais formal: "para acessar algum membro declarado pela classe do objeto referenciado pela variável). É como se, na hora de compilar, o Java topasse com o texto “totoh.brincar()” e pensasse(!): “Hmn! O programador tá me dizendo que essa variável ‘totoh’ referencia um objeto de uma classe, e que essa classe tem um método chamado ‘brincar’, e ele quer que eu(Java) execute esse método… Beleza, deixa eu ver se consigo fazer isso…” Nesse momento o Java vai na memória ver qual é o tipo, qual é a classe do objeto referenciado por totoh é, nesse caso, constata que é um objeto do tipo Cao. Então, vai verificar se por acaso o tal método brincar existe na classe Cao. Como nesse caso ele encontra o método, beleza!
O problema com seu código se dá justamente no momento em que o Java tenta saber qual é a classe do objeto referenciado pela posição 0 do vetor func! Como vimos anteriormente, func[0] estava fazendo referência a null, e null não é de nenhuma classe, aliás, null é algo como uma “ausência de objeto”! Vamos ver como que o Java se vira quando ele topa com o seu “[i]func.nome = “Rafael”;”:
Bom, palhacadinhas a parte, é isso o que acontece no seu código:
[i]func é uma referência para null, e você tenta acessar algum membro a partir dela. Isso faz o Java lançar uma NullPointerException.
O que você deveria fazer para evitar isso então? Simples! func não é um vetor de objetos do tipo Funcionario? Então você deve - antes de sair fazendo [i]func.isso, [i]func.aquilo, [i]func.aquilo_outro - providenciar um objeto Funcionario para a tal posição i de func! Algo do tipo:
Isso, claro, partindo do pressuposto que a sua classe Funcionario tenha um construtor sem parâmetros (construtor default).
Eu utilizei alguns termos neste tópico de forma, por vezes, um pouco inapropriada, mas que no dia-a-dia acabamos utilizando assim mesmo e nos entendendo. Sendo assim, sugiro fortemente que dê uma lida neste artigo. Além de tratar de um tema super importante, de base, é super didático e é até mesmo um tanto divertido. NÃO DEIXE DE LER ISSO!!!
Quanto à forma que você utilizou para resolver o problema, quero te dar uma sugestão: Que tal dar uma estudada sobre construtores e então refazer este problema? :thumbup: [color=darkblue][size=18]Observação[/size][/color]
É muito provável que meu post venha a repetir o que já foi respondido por alguém aqui, ainda mais que eu saí pra almoçar no meio da escrita… Minhas sinceras desculpas aos plagiados… :lol:
Quando tiver um filho vou colocar o nome de vocês cara…auhauahhua
Acho que esse tópico me fez entender em menos de um dia tudo que eu pensava que sabia. Não levei a sério na facul e agora quero aprender de verdade. Comecei ontem ler com mais propriedade e empenho a apostila da Caelum.
O “ruim” que depois que comecei a ler esse fórum, fiquei na dúvida:
Desistir de Java. Baseado no nível de conhecimento da galera daqui e visto que eu só sei fazer um “Hello World” (em modo texto) sem dar erros.
ou
Definitivamente aprender isso aqui devido à ajuda como a desse tópico.
Sobre o NullPointerException, dei uma lida por aqui e consegui resolver o problema.
Quanto à observação 5 que eu tinha feito, é o seguinte:
Você estava tentando adicionar um funcionário que já estava adicionado (pois vc estava passando o funcionário na posição 1 do array ao método adiciona, o que iria colocar o objeto da posição 1 na posição 0 - já que era a primeira vez que vc estava chamando o método adiciona e, inicialmente, o valor do atributo i da classe Empresa é 0)
Quando você faz isso:
for (int i=0; i<a.func.length; i++){
a.func[i] = new Funcionario();
}
Você está criando os objetos Funcionario. Mas você não vai poder nunca utilizar o método adiciona(Funcionario f) adequadamente dessa forma.
Qual o problema?
Quando você faz:
int i = 0;
a.func[i].nome = "Rafael";
a.func[i].depto = "Java";
a.func[i].sal = 1500;
Você já está preenchendo o func[0]. Ou seja, não precisa você fazer
a.adiciona(a.func[0]);
Mas o pior ainda está por vir… à medida que você vai preenchendo o array de Funcionarios dessa forma, você não está atualizando aquele valor do atributo i da classe Empresa. Então, veja bem… se, depois de você ter adicionado Rafal e Ana dessa forma, tentar adicionar um novo Funcionario usando o método adiciona, ele vai ser colocado em func[0], porque o valor do atributo i é 0… Com isso, você estará perdendo as informações do funcionário Rafael… Se depois disso, vc tentar adicionar um outro funcionário, você vai perder as informações de Ana… e assim por diante…
O que você precisa fazer para melhorar a forma de adicionar os funcionários é:
class mainEmpresa{
public static void main (String args[]){
Empresa a = new Empresa();
a.setNome("IBTA");
a.setCnpj("123456789");
Funcionario funcionario1 = new Funcionario();
funcionario1.setNome("Rafael");
funcionario1.setDepto("Java");
funcionario1.setSal(1500);
a.adiciona(funcionario1);
Funcionario funcionario2 = new Funcionario();
funcionario1.setNome("Ana");
funcionario1.setDepto("C++");
funcionario1.setSal(1000);
a.adiciona(funcionario2);
//a.func[0].imprimir(); Isso aqui você não pode fazer porque a.func[0] é um Funcionario... e a classe Funcionario não tem um método imprimir. Pelos códigos que vi até agora apenas a classe Empresa o tem.
}
}
Agora, é possível criar um método imprimir dentro da classe Empresa que chama o método imprimir da classe Funcionario (já existe nesse classe, não coloquei aqui porque não achei necessário)?
Outro ponto, tive que declarar o vetor func dentro da classe Empresa, depois tive que declarar e instanciar tbm dentro da classe mainEmpresa, é isso mesmo?
Pode sim, desde que o método imprimir da classe Funcionario seja acessível à classe Empresa. Vou colocar aqui uma sugestão de implementação para o método imprime:
public void imprime() {
System.out.println(nome + " - " + cnpj);
/*
* Agora vamos imprimir, um a um, os funcionários da empresa.
*/
for (Funcionario funci : func)
/*
* Cabe aqui uma dúvida: Será que o método imprime da classe
* Funcionario pula uma linha no final? Vamos assumir que sim...
*/
funci.imprime();
}
Então… Não há a necessidade de criar um novo vetor lá na classe MainEmpresa. Você pode, dentro do primeiro laço for (Agora que o imprime da classe Empresa já imprime os funcionários, o outro for pode ser apagado), criar um objeto Funcionario temporário. Algo assim:
import javax.swing.JOptionPane;
public class MainEmpresa {
public static void main(String[] args) {
Empresa e = new Empresa("IBTA", "99.999.999/9999-99");
for (int f = 0; f < e.getMaxFuncis(); f++) {
Funcionario tmp = new Funcionario();
tmp.nome = JOptionPane.showInputDialog ("Nome: ");
tmp.depto = JOptionPane.showInputDialog ("Departamento: ");
e.adiciona(tmp);
}
e.imprime();
}
}
Você deve ter notado que fiz pequenas alterações nos eu código. Vou fazer, mais tarde, uma outra implementação deste exercício pra você poder estudar uma outra solução.