Erro Exception in thread

Olá, pessoal, estou com o seguinte problema:
Estou desenvolvendo um programa de orçamento e preciso pegar métodos de outras classes mas está dando erro de exceção:

"Exception in thread “main” java.lang.StackOverflowError
at Dorso.(Dorso.java:4)
at Custos.(Custos.java:30)

Na verdade ta dando um loop infinito chamando um classe dentro da outra, mas o que poderia fazer para usar os métodos de outras classes sendo que quando eu declaro objetos para usá-los os “métodos tipo boolean que fiz” da erro de “null pointer exception”. Vou colocar um exemplo do que eu precisaria fazer tenho a classe: Dorso

public class Dorso extends Custos{

public double dorso() {
	double folhas;
	double total;

	BigDecimal bTotal;
	BigDecimal bTotal2;

	double conversao = 0;

	String papelGram [] = {"CB115", "CF115", "CB150", "CB170"};		


	if (papelGram[0] == getPapel()) {
		folhas = getPags() / 2;
		total = folhas * 0.11;				

		bTotal = new BigDecimal(total).setScale(1, RoundingMode.FLOOR);
		bTotal2 = bTotal.setScale(0, RoundingMode.CEILING);	
		
		conversao = bTotal2.doubleValue();				

	} else if (papelGram[1] == getPapel()) {
		folhas = getPags() / 2;
		total = folhas * 0.14;

		bTotal = new BigDecimal(total).setScale(1, RoundingMode.FLOOR);
		bTotal2 = bTotal.setScale(0, RoundingMode.CEILING);

		conversao = bTotal2.doubleValue();

	} else if (papelGram[2] == getPapel()) {
		folhas = getPags() / 2;
		total = folhas * 0.14;

		bTotal = new BigDecimal(total).setScale(1, RoundingMode.FLOOR);
		bTotal2 = bTotal.setScale(0, RoundingMode.CEILING);

		conversao = bTotal2.doubleValue();
		
	} else if (papelGram[3] == getPapel()) {
		folhas = getPags() / 2;
		total = folhas * 0.15;

		bTotal = new BigDecimal(total).setScale(1, RoundingMode.FLOOR);
		bTotal2 = bTotal.setScale(0, RoundingMode.CEILING);

		conversao = bTotal2.doubleValue();			

	} else {
		System.out.println("Campo vazio, ou nome inválido");	
	}	

	return conversao;
}
}

e a Classe Contatos2

import java.math.BigDecimal;
import java.math.RoundingMode;

public class Contatos2 extends Dorso {		
	
	 
	private double corteDuplo = 0;

	private double tamMaxLar = 0;
	private double tamMaxAlt = 0;
	
	
	public Contatos2() {
		super();

	}

	public double getCorteDuplo() {
		return corteDuplo;
	}

	public void setCorteDuplo(double corteDuplo) {
		this.corteDuplo = corteDuplo;
	}

	public double getTamMaxLar() {
		return tamMaxLar;
	}

	public void setTamMaxLar(double tamMaxLar) {
		this.tamMaxLar = tamMaxLar;
	}

	public double getTamMaxAlt() {
		return tamMaxAlt;
	}

	public void setTamMaxAlt(double tamMaxAlt) {
		this.tamMaxAlt = tamMaxAlt;
	}


	public boolean verificarTamMaxDuplo1() {

		boolean check = false;

		tamMaxLar = 46.8;
		tamMaxAlt = 31.8;

		if ((getFormatoLarg() <= tamMaxLar) && (getFormatoAlt() <= tamMaxAlt)) {
			check = true;

		} else {
			check = false;
		}
		return check;
	}

	public boolean verificarTamMaxDuplo2() {

		boolean check = false;

		tamMaxLar = 31.8;
		tamMaxAlt = 46.8;

		if ((getFormatoLarg() <= tamMaxLar) && (getFormatoAlt() <= tamMaxAlt)) {
			check = true;

		} else {
			check = false;
		}
		return check;
	}

	public boolean verificarTamMaxSeco1() {

		boolean check = false;

		tamMaxLar = 46.5;
		tamMaxAlt = 31.5;

		if ((getFormatoLarg() <= tamMaxLar) && (getFormatoAlt() <= tamMaxAlt)) {
			check = true;

		} else {
			check = false;
		}
		return check;
	}

	public boolean verificarTamMaxSeco2() {

		boolean check = false;

		tamMaxLar = 31.5;
		tamMaxAlt = 46.5;

		if ((getFormatoLarg() <= tamMaxLar) && (getFormatoAlt() <= tamMaxAlt)) {
			check = true;

		} else {
			check = false;
		}
		return check;
	}

	public double corteDuplo() {

		double multContatos = 0;	

		double tamCorteDuploLar = getFormatoLarg() + (getCorteDuplo() / 10);
		double contatosDuploLar = tamMaxLar / tamCorteDuploLar;
		BigDecimal bcontatosDuploLar = new BigDecimal(contatosDuploLar).setScale(0, RoundingMode.DOWN);
		double convContatosDuploLar = bcontatosDuploLar.doubleValue();

		double tamCorteDuploAlt = getFormatoAlt() + (getCorteDuplo() / 10);
		double contatosDuploAlt = tamMaxAlt / tamCorteDuploAlt;
		BigDecimal bcontatosDuploAlt = new BigDecimal(contatosDuploAlt).setScale(0, RoundingMode.DOWN);
		double convContatosDuploAlt = bcontatosDuploAlt.doubleValue();

		multContatos = ((convContatosDuploLar) * (convContatosDuploAlt));

		return multContatos;

	}
	
	public double corteDuploCanoa() {

		double multContatos = 0;	
		//Dobrar o tamanho da largura do miolo para usar no cálculo de contatos da capa
		double tamCorteDuploLar = ((getFormatoLarg() * 2) + (getCorteDuplo() / 10));
		double contatosDuploLar = tamMaxLar / tamCorteDuploLar;
		BigDecimal bcontatosDuploLar = new BigDecimal(contatosDuploLar).setScale(0, RoundingMode.DOWN);
		double convContatosDuploLar = bcontatosDuploLar.doubleValue();

		double tamCorteDuploAlt = getFormatoAlt() + (getCorteDuplo() / 10);
		double contatosDuploAlt = tamMaxAlt / tamCorteDuploAlt;
		BigDecimal bcontatosDuploAlt = new BigDecimal(contatosDuploAlt).setScale(0, RoundingMode.DOWN);
		double convContatosDuploAlt = bcontatosDuploAlt.doubleValue();

		multContatos = ((convContatosDuploLar) * (convContatosDuploAlt));

		return multContatos;

	}
	
	public double corteDuploLombada() {

		double multContatos = 0;	
		//Dobrar o tamanho da largura do miolo para usar no cálculo de contatos da capa
		double tamCorteDuploLar = (((getFormatoLarg() * 2) + (dorso() / 10)) + (getCorteDuplo() / 10));
		double contatosDuploLar = tamMaxLar / tamCorteDuploLar;
		BigDecimal bcontatosDuploLar = new BigDecimal(contatosDuploLar).setScale(0, RoundingMode.DOWN);
		double convContatosDuploLar = bcontatosDuploLar.doubleValue();

		double tamCorteDuploAlt = getFormatoAlt() + (getCorteDuplo() / 10);
		double contatosDuploAlt = tamMaxAlt / tamCorteDuploAlt;
		BigDecimal bcontatosDuploAlt = new BigDecimal(contatosDuploAlt).setScale(0, RoundingMode.DOWN);
		double convContatosDuploAlt = bcontatosDuploAlt.doubleValue();

		multContatos = ((convContatosDuploLar) * (convContatosDuploAlt));

		return multContatos;

	}

	public double corteSeco() {

		double multContatos = 0;

		double contatosLarg = tamMaxLar / getFormatoLarg();
		double contatosAlt = tamMaxAlt / getFormatoAlt();

		BigDecimal bcontatosLarg = new BigDecimal(contatosLarg).setScale(0, RoundingMode.DOWN);
		double convContatosLarg = bcontatosLarg.doubleValue();
		//double tamTotalLar = getFormatoLarg() * convContatosLarg;

		BigDecimal bcontatosAlt = new BigDecimal(contatosAlt).setScale(0, RoundingMode.DOWN);
		double convContatosAlt = bcontatosAlt.doubleValue();
		//double tamTotalAlt = getFormatoAlt() * convContatosAlt;

		multContatos = convContatosLarg * convContatosAlt;

		return multContatos;
	}	
	
	

	public double contatosMiolo1() {

		double num = 0;

		if (verificarTamMaxDuplo1() && getCorteDuplo() > 0) {
			num = corteDuplo();			

		} else if (verificarTamMaxSeco1()) {
			num = corteSeco();			
			
		} else {
			System.out.println("Tamanho não suportado");			
		}

		return num;

	}

	public double contatosMiolo2() {

		double num = 0;

		if (verificarTamMaxDuplo2() && getCorteDuplo() > 0) {
			num = corteDuplo();			

		} else if (verificarTamMaxSeco2()) {
			num = corteSeco();			
			
		} else {
			System.out.println("Tamanho não suportado");			
		}

		return num;

	}
	
	public double contatosCapa1() {

		double num = 0;

		if (verificarTamMaxDuplo1() && getCorteDuplo() > 0) {
			if (acabCanoa() == true) {
				num = corteDuploCanoa();
						
			} else if (acabLombQuadrada() == true) {
				num = corteDuploLombada();
				
			} 

		} else {
			System.out.println("Tamanho não suportado");			
		}

		return num;

	}
	
	public double contatosCapa2() {

		double num = 0;

		if (verificarTamMaxDuplo2() && getCorteDuplo() > 0) {
			if (acabCanoa() == true) {
				num = corteDuploCanoa();
						
			} else if (acabLombQuadrada() == true) {
				num = corteDuploLombada();
				
			} 

		} else {
			System.out.println("Tamanho não suportado");			
		}

		return num;

	}

	public double checkContatosMiolo() {
		double contatos = 0;	

		if (contatosMiolo1() > contatosMiolo2()) {			
			//System.out.println(contatos1());
			contatos = contatosMiolo1();
		} else {
			//System.out.println(contatos2());
			contatos = contatosMiolo2();
		}
		
		return contatos;

	}
	
	public double checkContatosCapa() {
		double contatos = 0;	

		if (contatosCapa1() > contatosCapa2()) {
			contatos = contatosCapa1();
		} else {
			contatos = contatosCapa2();
		}
		
		return contatos;

	}

	public static void main(String[] args) {
		Contatos2 c = new Contatos2();
		
		

		c.setQuant(2);
		c.setPags(120);
		c.setPapel("CB150");
		c.setFormatoLarg(5);
		c.setFormatoAlt(9);
		
		c.setAcabCanoa2("");
		c.setAcabLomb2("X");
		

		c.setCorteDuplo(3);		
			
		System.out.println(c.dorso() + " mm dorso");
		
		System.out.println(c.checkContatosMiolo() + " contato miolo");
		System.out.println(c.checkContatosCapa() + " contato capa");
		

	}




}

Nela mesma eu coloquei o método “Main” só pra teste, tem a classe Custos

public class Custos {

	private double impressao;
	private double fatorLucro;
	private boolean tipoAcabamento = false;
	private String papel;

	private double pags = 0;
	private double formatoLarg = 0;
	private double formatoAlt = 0;
	private double quant;

	private double acabCanoa = 0;
	private double acabLomb = 0;
	private double acabWireEspiral = 0;

	private double contatos = 0;

	private String acabCanoa2 = null;
	private String acabLomb2 = null;
	private String acabWireEspiral2 = null;

	private double valorCapa = 0;
	private double contatoCapa = 0;

	private String capaFrente = null;
	private String capaFrenteVerso = null;	

	Dorso d = new Dorso();

	public Custos() {		

	}



	public double getAcabWireEspiral() {
		return acabWireEspiral;
	}




	public void setAcabWireEspiral(double acabWireEspiral) {
		this.acabWireEspiral = acabWireEspiral;
	}




	public String getAcabWireEspiral2() {
		return acabWireEspiral2;
	}




	public void setAcabWireEspiral2(String acabWireEspiral2) {
		this.acabWireEspiral2 = acabWireEspiral2;
	}




	public String getCapaFrenteVerso() {
		return capaFrenteVerso;
	}


	public void setCapaFrenteVerso(String capaFrenteVerso) {
		this.capaFrenteVerso = capaFrenteVerso;
	}


	public String getCapaFrente() {
		return capaFrente;
	}


	public void setCapaFrente(String capaFrente) {
		this.capaFrente = capaFrente;
	}


	public double getContatoCapa() {
		return contatoCapa;
	}




	public void setContatoCapa(double contatoCapa) {
		this.contatoCapa = contatoCapa;
	}




	public double getValorCapa() {
		return valorCapa;
	}




	public void setValorCapa(double valorCapa) {
		this.valorCapa = valorCapa;
	}




	public String getAcabCanoa2() {
		return acabCanoa2;
	}




	public void setAcabCanoa2(String acabCanoa2) {
		this.acabCanoa2 = acabCanoa2;
	}




	public String getAcabLomb2() {
		return acabLomb2;
	}




	public void setAcabLomb2(String acabLomb2) {
		this.acabLomb2 = acabLomb2;
	}




	public double getContatos() {
		return contatos;
	}



	public void setContatos(double contatos) {
		this.contatos = contatos;
	}



	public double getAcabCanoa() {
		return acabCanoa;
	}

	public void setAcabCanoa(double acabCanoa) {
		this.acabCanoa = acabCanoa;
	}

	public double getAcabLomb() {
		return acabLomb;
	}

	public void setAcabLomb(double acabLomb) {
		this.acabLomb = acabLomb;
	}

	public double getImpressao() {
		return impressao;
	}

	public void setImpressao(double impressao) {
		this.impressao = impressao;
	}

	public double getFatorLucro() {
		return fatorLucro;
	}

	public void setFatorLucro(double fatorLucro) {
		this.fatorLucro = fatorLucro;
	}


	public String getPapel() {
		return papel;
	}

	public void setPapel(String papel) {
		this.papel = papel;
	}

	public boolean getTipoAcabamento() {
		return tipoAcabamento;
	}

	public void setTipoAcabamento(boolean tipoAcabamento) {
		this.tipoAcabamento = tipoAcabamento;
	}

	public double getPags() {
		return pags;
	}

	public void setPags(double pags) {
		this.pags = pags;
	}

	public double getFormatoLarg() {
		return formatoLarg;
	}

	public void setFormatoLarg(double formatoLarg) {
		this.formatoLarg = formatoLarg;
	}

	public double getFormatoAlt() {
		return formatoAlt;
	}

	public void setFormatoAlt(double formatoAlt) {
		this.formatoAlt = formatoAlt;
	}

	public double getQuant() {
		return quant;
	}

	public void setQuant(double quant) {
		this.quant = quant;
	}

	public boolean acabCanoa () {
		if (getAcabCanoa2().isEmpty()) {		
			return false;

		} else {			
			return true;
		}
	}

	public boolean multiploDeQuatro() {	
		if ((getPags() % 4) == 0) {
			return true;
		} else {
			return false;
		}

	}

	public boolean formatoLombadaCanoa() {		
		double formatoMaximoAlt = 31.5;
		double formatoMaximoLarg = 46.5;

		if((getFormatoLarg() * 2) <= formatoMaximoLarg && getFormatoAlt() <= formatoMaximoAlt) {
			return true;

		} else {
			return false;
		}

	}

	public boolean acabLombQuadrada() {
		if (getAcabLomb2().isEmpty()) {
			return false;

		} else {
			return true;
		}
	}

	public boolean formatoLombadaQuadrada() {
		double formatoMaximoAlt = 31.5;
		double formatoMaximoLarg = 46.5;

		if(((d.dorso() / 10) + (getFormatoLarg() * 2)) <= formatoMaximoLarg && getFormatoAlt() <= formatoMaximoAlt) {
			return true;

		} else {
			return false;

		}
	}



	public boolean acabWireEspiral() {

		if (getAcabWireEspiral2().isEmpty()) {
			return false;

		} else {
			return true;
		}
	}

	public boolean formatoLombadaWireoEspiral() {		

		double formatoMaximoAlt = 31.5;
		double formatoMaximoLarg = 46.5;	

		if((getFormatoLarg()) <= formatoMaximoLarg && getFormatoAlt() <= formatoMaximoAlt) {		
			return true;

		} else {		
			return false;
		}		
	}

}

Olá,
é que Dorso extende Custos. Porem quando vc cria uma objeto Custos, ele precisa criar um objeto Dorso (Dorso d = new Dorso()).
Uma classe está dependendo da outra, e vice-versa, oq gera uma referência circular. Não pode fazer assim, precisa mudar sua lógica. Pode passar Dorso por parâmetro pra Custos.

Olá, Rodrigo, então sou iniciante em java e não entendi muito bem o que vc quis dizer, seria isso:
Teria que tirar o “extends Custos” e só instanciar o objeto como " Custos c = new Custos()" na classe “Dorso”?

Grato

Não. Creio que seu entendimento de herança (extends) não esteja legal. Não vejo necessidade de usar herança neste contexto. Também não entendi qual o objetivo destes códigos.
Se vc precisa chamar um método de outra classe NÃO É ASSIM que se faz:
Custos c = new Custos():-1:
Não é simplesmente criar um objeto qualquer para conseguir acesso ao método. Os objetos possuem atributos com seus valores, se não usar o objeto que contem estes valores não adianta chamar o método.
Exemplo:
Se no método formatoLombadaQuadrada vc precisa usar algo de um objeto dorso, vc passa ele por parâmetro pro método:
public boolean formatoLombadaQuadrada(Dorso dorso) {

certo nesse ficaria assim exemplo:
tenho um método que usaria da Classe “Dorso” que está na classe “Contatos2”

public double corteDuploLombada(Dorso dorso){

double multContatos = 0;	
//Dobrar o tamanho da largura do miolo para usar no cálculo de contatos da capa
double tamCorteDuploLar = (((getFormatoLarg() * 2) + (dorso.dorso() / 10)) + (getCorteDuplo() / 10));
double contatosDuploLar = tamMaxLar / tamCorteDuploLar;
BigDecimal bcontatosDuploLar = new BigDecimal(contatosDuploLar).setScale(0, RoundingMode.DOWN);
double convContatosDuploLar = bcontatosDuploLar.doubleValue();

double tamCorteDuploAlt = getFormatoAlt() + (getCorteDuplo() / 10);
double contatosDuploAlt = tamMaxAlt / tamCorteDuploAlt;
BigDecimal bcontatosDuploAlt = new BigDecimal(contatosDuploAlt).setScale(0, RoundingMode.DOWN);
double convContatosDuploAlt = bcontatosDuploAlt.doubleValue();

multContatos = ((convContatosDuploLar) * (convContatosDuploAlt));

return multContatos;

}

Isso, melhor assim.

Mais uma dúvida se eu passar como parâmetro em alguns métodos eu uso o resultado desse método junto com if e else" e como eles agora tem parâmetro não tem como eu aplicar ele na lógica veja:

1º - Fiz o parâmetro neste método:
public double contatosCapa1(Acabamentos a) {

	double num = 0;

	if (verificarTamMaxDuplo1() && getCorteDuplo() > 0) {
		if (a.acabCanoa() == true) {
			num = corteDuploCanoa();
					
		} else if (a.acabLombQuadrada() == true) {
			num = corteDuploLombada();
			
		} 

	} else {
		System.out.println("Tamanho não suportado");			
	}

	return num;

}

public double contatosCapa2(Acabamentos a) {

	double num = 0;

	if (verificarTamMaxDuplo2() && getCorteDuplo() > 0) {
		if (a.acabCanoa() == true) {
			num = corteDuploCanoa();
					
		} else if (a.acabLombQuadrada() == true) {
			num = corteDuploLombada();
			
		} 

	} else {
		System.out.println("Tamanho não suportado");			
	}

	return num;

}

Agora tem um outro método que faço para descobrir quantos contatos darão entre esse dois métodos e retorna o valor
do maior, mas como agora tem parâmetro como eu faria??

	public double checkContatosCapa() {
	double contatos = 0;	

	if (contatosCapa1() > contatosCapa2()) {
		contatos = contatosCapa1();
	} else {
		contatos = contatosCapa2();
	}
	
	return contatos;

}

Vc vai ter que ir passando por parâmetro nos métodos até onde for usar o objeto. Ou podes passar uma vez por parâmetro no construtor e sempre utilizar-se do mesmo sem precisar passar novamente. Ex:

Dorso dorso;
public Custos(Dorso dorso) {		
    this.dorso = dorso;
}

Desculpe Rodrigo não entendi muito bem, fiz um outro exemplo simples pra ver se vc poderia me explicar melhor veja
1º fiz uma outra classe “Custos” com apenas alguns atributos e métodos.

public class Custos {

private String acabLomb2;

Acabamentos a;
public Custos(Acabamentos a) {
	this.a = a;


}


public String getAcabLomb2() {
	return acabLomb2;
}


public void setAcabLomb2(String acabLomb2) {
	this.acabLomb2 = acabLomb2;
}


public static void main(String[] args) {
	Custos c = new Custos();

	c.setAcabLomb2("x");

}

}

2º Fiz uma outra classe chama Acabamentos com apenas um método (daquele jeito que vc falou)
public class Acabamentos {

public boolean acabLombQuadrada(Custos c) {
	if (c.getAcabLomb2().isEmpty()) {
		return false;

	} else {			
		System.out.println("Não está vazia");
		return true;
	}
}

}

Gostaria de fazer funcionar o método que está no acabamento mas daquele jeito que vc disse seu usar HERANÇA somente com objeto.

Antes de mais nada, pq tem um atributo Acabamentos na classe Custos ?
Ele não está sendo usado.

Só fiz um exemplo pq a classe “custo” terá todos os atributos e métodos getter e setter que influenciam no custo de um material, e o acabamento é um deles que na verdade será passado por um método “set” onde será colocado um “x” caso esse método for utilizado e para fazer isso funcionar eu coloquei um boolean (em outra classe que nomeie como acabamento) para verificar se estiver vazio vai aparecer aquela mensagem senão vai dar certo (esse método boolean será usado em outro método que terá relação com outros custos que serão influenciado se este for colocado o “x”.

Mas gostaria de saber como fazer a ligação disso tudo para usar no método (main).