2015-11-02, 03:24
  #1
Medlem
Tom.Of.Finlands avatar
Hej!

Jag har en klass som jag kallar för klass1. I klass1 så finns det en klass som heter klass2. Klass2 är en array-klass dvs jag skapar olika objekt av klass2 i klass1.

När jag skapar ett objekt av klass1 och anropar en metod som "går in" i ett objekt av klass2 så får jag detta meddelande:

Kod:
Exception in thread "main" java.lang.NullPointerException
	at projekt.kvittolista.lista.nyTransaktion(lista.java:74)
	at projekt.kvittolista.ProjektKvittolista.main(ProjektKvittolista.java:44)
Java Result: 1

Och klass2 som är i klass1, säger att objektet OBJ "Field OBJ can be final".

Vad menas? Vad ska jag göra?

EDIT! Jag satte OBJ som "final". Så nu är det error borta.
Citera
2015-11-02, 09:35
  #2
Moderator
Protons avatar
Citat:
Ursprungligen postat av Tom.Of.Finland
Hej!

Jag har en klass som jag kallar för klass1. I klass1 så finns det en klass som heter klass2. Klass2 är en array-klass dvs jag skapar olika objekt av klass2 i klass1.

När jag skapar ett objekt av klass1 och anropar en metod som "går in" i ett objekt av klass2 så får jag detta meddelande:

Kod:
Exception in thread "main" java.lang.NullPointerException
	at projekt.kvittolista.lista.nyTransaktion(lista.java:74)
	at projekt.kvittolista.ProjektKvittolista.main(ProjektKvittolista.java:44)
Java Result: 1

Och klass2 som är i klass1, säger att objektet OBJ "Field OBJ can be final".

Vad menas? Vad ska jag göra?

EDIT! Jag satte OBJ som "final". Så nu är det error borta.
Omöjligt att svara på vad som hände, eller ens om du löst problemet korrekt utan att se nån kod. Just nu kan det beror på att planeterna står fel, eller att kaffesumpen lade sig i en ofördelaktig position i morse....
Citera
2015-11-02, 13:41
  #3
Medlem
Tom.Of.Finlands avatar
Korkad jag är!

Jag laddar upp projektet!

http://s000.tinyupload.com/index.php...03780121654857

Det är i NetBeans Format. Men ni kanske löser det på något annat sätt?

För den fete och late som inte vågar ladda ner filerna.....så postar jag koden direkt. Inte så mycket.

Kod:
package projekt.kvittolista;

import java.util.Scanner;


public class ProjektKvittolista 
{

    public static void main(String[] args) 
    {   
        /* Deklarerar variabler */
        int x = -1; // Att börja med så loopen fungerar tills x == 0
        String namn;
        
        /*Skapar ett objekt från klassen lista */
        lista L = new lista(); // Objekt
        
        /*Skapa ett objekt från klassen scanner */
        Scanner input = new Scanner(System.in);
        
        while(x != 0)
        {
            System.out.println("Välj i menyn nedan: ");
            System.out.println("0. Avsluta. Alla transaktioner sparas på fil.");
            System.out.println("1. Läs in en transaktion från tangentbordet.");
            System.out.println("2. Skriv ut information om alla transaktioner.");
            System.out.println("3. Beräkna totala kostnaden.");
            System.out.println("4. Hur mycket är en viss person skyldig?");
            System.out.println("5. Hur mycket ligger en viss person ute med?");
            System.out.println("6. Lista alla personer mm och FIXA!!!");
            System.out.println("Skriv här: ");
            x = input.nextInt();
            System.out.println(""); // Ny rad bara.
            
            switch(x) // Switch för att gå in i olika selektorer.
            {
                case 0:
                    System.out.println("Du har valt att skriva alla kvitton till en gemensam fil.");
                    L.sparaKvittoFil();
                    break;
                case 1:
                    System.out.println("Du har valt att lägga till en ny transaktion.");
                    L.nyTransaktion();
                    break;
                case 2:
                    System.out.println("Du har valt att skriva ut alla transaktioner");
                    L.skrivUtAllaKvitton();
                    break;
                case 3:
                    System.out.println("Du har valt att beräkna totala kostnaden för alla transaktioner");
                     L.totalKostnad();
                    break;
                case 4:
                    System.out.println("Du har valt att visa hur mycket en viss person är skyldig");
                    System.out.print("Vad heter personen?: ");
                    namn = input.next();
                    L.getNamnSkyldig(namn);
                    break;
                case 5:
                    System.out.println("Du har valt att visa hur mycket en viss person har legat ute med");
                    System.out.print("Vad heter personen?: ");
                    namn = input.next();
                    L.getNamnBetalt(namn);
                    break;
                case 6:
                    System.out.println("Du har valt att skriva ut en lista hur mycket en person är skyldig och har betalat");
                    L.listaResultat();
                    break;
                default:
                    System.out.println("Fel inmatning");
                    x = -1;
                    break;
            }
        }
    }
}
__________________
Senast redigerad av Tom.Of.Finland 2015-11-02 kl. 13:50.
Citera
2015-11-02, 13:48
  #4
Medlem
Tom.Of.Finlands avatar
Kod:
package projekt.kvittolista;

import java.io.*;
import java.util.Scanner;

public class lista 
{
    /* En konstant för att visa hur många element det är */
    int MAX = 10;
    
    private kvitto[] K = new kvitto[MAX];
    private person[][] P = new person[MAX][MAX];
    private int antalHandelser;
    
    /* En scanner! */
    Scanner input = new Scanner(System.in);
    
    /* Konstruktör för klassen lista */
    public lista()
    {
	antalHandelser = 0;
    }
    
    /* Set-metod som skriver ut och sparar allt på en fil */
    public void sparaKvittoFil()
    {
        /* Deklarera ett objekt */
        File fpw = new File("resa.txt");
        String mening;
        
        for (int i = 0; i < antalHandelser; i++)
        {
             
            mening = K[i].getDatum() + "\t" + K[i].getTjanst() + "\t" + K[i].getNamn() + "\t" + K[i].getPris() + "\t" + K[i].getAntalPersoner();
            
            for (int c = 0; c < K[i].getAntalPersoner(); c++)
            {
                mening = "\t" + K[i].getKompisar(c);
            }
            
            
            try {
                try (PrintWriter pw = new PrintWriter(fpw)) {
                    pw.write(mening);
                }
            } 
            catch (IOException e) 
            {
            }
        }
    }
    
    /* Set-metod för att skriva ntt kvitto/transaktion */
    public void nyTransaktion()
    {
	String datum;
	String tjanst;
	String namn;
	double pris;
	int antalPersoner;

	System.out.print("Vad är namnet på kvittot?: ");
	namn = input.next();
	K[antalHandelser].setNamn(namn);
        
        System.out.print("Vad är datumet på kvittot?: ");
        datum = input.next();
        K[antalHandelser].setDatum(datum);

	System.out.print("Vad heter tjänsten på kvittot?: ");
	tjanst = input.next();
	K[antalHandelser].setTjanst(tjanst);

	System.out.print("Vad är priset på kvittot?: ");
	pris = input.nextDouble();
	K[antalHandelser].setPris(pris);

	System.out.print("Vilka fler är med på kvittot?: ");
	antalPersoner = input.nextInt();
	K[antalHandelser].setAntalPersoner(antalPersoner);

	String[] tempArray = new String[antalPersoner]; // Temponär array som ska bara hålla i värden tillfälligt
	for (int i = 0; i < antalPersoner; i++)
	{
            System.out.printf("Vad heter person nummer %d ?: ", i+1);
            tempArray[i] = input.next();
	}
	/* Denna funktion tar med längden på tempArray och tempArray för att kopiera vidare över till namnKompisar[] i metoden */
	K[antalHandelser].setKompisar(tempArray);

	/* Lägg in hur mycket en person är skyldig och lägger undan */
	for (int i = 0; i < antalPersoner; i++)
	{
            P[antalHandelser][i].setSkyldig(tempArray[i], pris, antalPersoner);
	}
	/* Lägg in hur mycket en person har betalat vid transaktionen.
	Variabeln antalPersoner + 1 står för den sista personen som är alltid den som betalade.		*/
	P[antalHandelser][antalPersoner + 1].setBetald(namn, pris, antalPersoner);

	antalHandelser++; // Räkna!

    }
    
    /* Get-metod som skriver ut alla kvitton rad efter rad */
    public void skrivUtAllaKvitton()
    {
	String mening = "";
	System.out.print("Datum\tTjänst\tNamn\tPris\tAntal personer\tÖvriga namn");
	System.out.print("\n");
	for (int i = 0; i < antalHandelser; i++)
	{
      
            mening = K[i].getDatum() + "\t" + K[i].getTjanst() + "\t" + K[i].getNamn() + "\t" + String.valueOf(K[i].getPris()) + "\t" + String.valueOf( K[i].getAntalPersoner());

            /* For-loop som lägger på de namn på kvittot som inte betalade för sig, i variabeln mening */
            for (int c = 0; c < K[i].getAntalPersoner(); c++)
            {
                mening += "\t" + K[i].getKompisar(c);
            }

            System.out.println(mening);
	}
        System.out.print("\n"); // Ny rad bara! 
    }
    
    
    /* Get-metod som hämtar alla priser på alla kvitton/transaktioner, summerar dessa och skriver ut */
    public void totalKostnad()
    {
        /* Variabeln antalHandelser är hur många transaktioner/kvitton som har skrivits */
	double totalPris = 0.0;
	for (int i = 0; i < antalHandelser; i++)
	{
            totalPris += K[i].getPris();
	}

	System.out.printf("Den totala summan är: %d\n\n", totalPris);

    }
    
    /* Get-metod som räknar ut hur mycket ett visst namn har betalat för sig */
    public void getNamnBetalt(String namn)
    {
        double betalt = 0.0;
        for (int x = 0; x < antalHandelser; x++)
        {
            /* Det är svårt att avgöra det sista y:et i P[x][y] så alla index går igenom för att söka efter namnet som betalade */
            for (int y = 0; y < MAX; y++)
            {
		betalt += P[x][y].getBetalt(namn, 'B'); // Det är alltid det sista y i index som är den som har betalat.
            }
	}
	
        System.out.printf("Personen %s har betalat %d\n\n", namn, betalt);

    }
    
    /* Get-metod som räknar ut hur mycket ett visst namn har betalat för sig */
    public void getNamnSkyldig(String namn)
    {
	double skyldig = 0.0;
	for (int x = 0; x < antalHandelser; x++)
	{
            /* Det är svårt att avgöra det första y:et till näst sista y:et i P[x][y] så alla index går igenom för att söka efter namnet är skyldig */
            for (int y = 0; y < MAX; y++)
            {
		skyldig += P[x][y].getSkyldig(namn, 'S'); // y = 0 till näst sista y är de namn som är skyldiga.
            }
	}

        System.out.printf("Personen %s är skyldig: %d\n\n", namn, skyldig);
    }
    
    /* Get-metod för att skriva ut den totala summan hur mycket en person är skyldig och ska betala till en pott */
    public void listaResultat()
    {
	/* Sätt alla element i arrayen namn[] till "" får att kunna avgöra om dem är tom eller inte */
	String[] namn = new String[MAX]; // Sammla de existerade namnen
	for (int i = 0; i < MAX; i++)
	{
            namn[i] = ""; // Nollställ
	}

	int z = 0; // z räknar ut hur många namn som programmet har i sig.
	/* For-For-loopen går igenom alla element [x][y] och kollar om namnen finns och sorterar dessa */
	for (int x = 0; x < antalHandelser; x++)
	{
            for (int y = 0; y < MAX; y++)
            {
		/* if-sats som retunerar true om namnet inte finns redan i arrayen namn[] */
		if (findStrInArray(namn, P[x][y].getNamn()))
                {
                    namn[z] = P[x][y].getNamn();
                    z++; // Räkna antalet namn som har skrivit in.
		}
            }
	}

	double skyldig = 0.0;
	double betalt = 0.0;
	/* z står för antalet namn som programmet känner till */
	for (int i = 0; i < z; i++)
	{
            /* Se kommentarerna för metoden lista::getNamnSkyldig(string namn)
	   och lista::getNamnBetalt(string namn). Det är samma sak som körs om igen*/
            for (int x = 0; x < antalHandelser; x++)
            {
                for (int y = 0; y < MAX; y++)
		{
                    skyldig += P[x][y].getSkyldig(namn[i], 'S');
		}
		for (int y = 0; y < MAX; y++)
		{
                    betalt += P[x][y].getBetalt(namn[i], 'B');
		}
            }

            if (betalt > skyldig)
            {
                /* Om en person har betalat mer än vad den är skyldig */
                System.out.printf("Personen %s ligger ute med och är skyldig. %s ska ha %d från potten\n", namn[i], betalt, skyldig, namn[i], betalt - skyldig);
            }
            else
            { 
                /*Om en person är mer skyldig än vad den har betalat */
                System.out.printf("Personen %s ligger ute med %d och är skyldig %d. %s och ska betala %d till potten\n", namn[i], betalt, skyldig, namn[i], skyldig - betalt);

            }

            skyldig = 0.0; // Nollställ - Viktigt!
            betalt = 0.0; // Nollställ - Viktigt!
        }

	System.out.printf("\n"); // Ny rad!
    }
    
    /* Get-metod som letar om namnet n finns i arrayen namn[] */
    public boolean findStrInArray(String[] namn, String n)
    {
        for (int i = 0; i < MAX; i++)
	{
            if (namn[i].equals(n))
            {
                return false; // Ja, den finns redan!
            }
	}

	return true; // Nej, det finns inget sånt namn i arrayen namn[]
    }
    
}
Citera
2015-11-02, 13:48
  #5
Medlem
Tom.Of.Finlands avatar
Kod:
package projekt.kvittolista;


public class kvitto 
{
    int MAX = 10;
    private String namn;
    private String tjanst;
    private String datum;
    private double pris;
    private int antalPersoner;
    private String[] kompisarNamn = new String[MAX];
    
    /* Konstruktören för klassen kvitto */
    public kvitto()
    {
        /* Viktigt att man börjar med några värden först */
	namn = "";
	tjanst = "";
	datum = "";
	pris = 0.0;
	antalPersoner = 0;

	for (int i = 0; i < MAX; i++)
	{
            kompisarNamn[i] = "";
	}
    }

    /* Set-metod för att bestämma namnet på den som betalade för transaktionen */
    public void setNamn(String n)
    {
        namn = n;
    }

    /* Set-metod för att sätta ett nytt namn på en tjänst */
    public void setTjanst(String t)
    {
        tjanst = t;
    }

    /* Set-metod för att beståmma datumet på en transaktion */
    public void setDatum(String d)
    {
        datum = d;
    }

    /* Set-metod för att bestämma priset på en transaktion */
    public void setPris(double p)
    {
	pris = p;
    }

    /* Set-metod för att sätta antal personer som tog del av transaktionen, men inte betalade.
    Antalpersoner + 1 motsvarar ALLA personer på ett kvitto */
    public void setAntalPersoner(int a)
    {
        antalPersoner = a;
    }

    /* Set-metod för att skriva in kompisarnanas namn i kvittot som tog del av transaktionen, men inte betalade */
    public void setKompisar(String[] k)
    {
        kompisarNamn = k;
    }

    /* Get-metod för att hämta namnet på personen som betalade för transaktionen */
    public String getNamn()
    {
        return namn;
    }

    /* Get-metod fär att hämta tjänsten på en transaktion */
    public String getTjanst()
    {
        return tjanst;
    }

    /* Get-metod för att hämta datumet på en transaktion */
    public String getDatum()
    {
	return datum;
    }

    /* Get-metod för att hämta priset på en transaktion */
    public double getPris()
    {
        return pris;
    }

    /* Get-metod för att hämta antalet personer på kvittot som tog det av transaktionen med inte betalade  */
    public int getAntalPersoner()
    {
	return antalPersoner;
    }

    /* Get-metod för att skicka ETT element från arrayen kompisarNamn[]*/
    public String getKompisar(int c)
    {
	return kompisarNamn[c];
    }
}

Kod:
package projekt.kvittolista;


public class person 
{
    private String namn;
    private double skyldig;
    private double betalat;
    private char SorB; // S för skyldig och B för betalat

    /* Konstruktören för klassen person */
    public person()
    {
	namn = "";
	skyldig = 0.0; // Viktigt att sätta ett värde att börja med
	betalat = 0.0; // Viktigt att sätta ett värde att börja med
    }
    
    /* Set-metod som sätter in värden om en person om hur mycket den är skyldig */
    public void setSkyldig(String namnSkyldiga, double pris, int antalPersoner)
    {
	skyldig = pris / (antalPersoner + 1);
	namn = namnSkyldiga;
	SorB = 'S'; // skyldig
    }

    /* Set-metod som sätter in värden om en person om hur mycket den har betalat */
    public void setBetald(String namnBetalt, double pris, int antalPersoner)
    {
	betalat = pris - pris / (antalPersoner + 1);
	namn = namnBetalt;
	SorB = 'B'; // betalat
    }

    /* Get-metod för att hämna personens namn*/
    public String getNamn()
    {
	return namn;
    }

    /* Get-metod som hämtar hur mycket en person är skyldig.
    Variabel val är avgörande om namnet har betalat för transaktionen eller är skyldig i transaktionen
    */
    public double getSkyldig(String namnSkyldig, char val)
    {
	/* SorB står för Skyldig eller Betalat */
	if (namn.equals(namnSkyldig) && SorB == val)
        {
            return skyldig;
        }
	else
	{
            return 0;
	}
    }

    /* Get-metod för att hämna hur mycket personen har betalat vid en transaktion.
    Variabel val är avgörande om namnet har betalat för transaktionen eller är skyldig i transaktionen
    */
    public double getBetalt(String namnBetalt, char val)
    {
        /* SorB står för Skyldig eller Betalat */
	if (namn.equals(namnBetalt) && SorB == val)
	{
            return betalat;
	}
	else
	{
            return 0;
	}
    }    
}
Citera
2015-11-02, 14:22
  #6
Medlem
Citat:
Exception in thread "main" java.lang.NullPointerException
at projekt.kvittolista.lista.nyTransaktion(lista.java :74)
at projekt.kvittolista.ProjektKvittolista.main(Projek tKvittolista.java:44)
Java Result: 1

Läser du ditt felmeddelande så ser du att programmet får en nullpointer på rad 74 i din class lista.java.

Då jag inte riktigt ser vilken rad detta är i din kod (din rad innehåller inte radnumrena) så är det jag kan på rak arm säga är att du instansierar en array med kvitton som du döpt till "K" (dåligt namn på en lista, använd engelska och inte svenska samt döp isf listan till "kvitton" om du ska använda svenska, istället för bara en enstaka bokstav) med variablen MAX antalet platser, i detta fall 10.

Så du har du skapat en tom array som kan hålla 10 kvitton.

Men senare i metoden "nyTransaktion" så antar du rakt av att arrayen är populerad med kvitton utan att kontrollera om det finns några kvitton i din array.

Kod:
System.out.print("Vad är namnet på kvittot?: ");
    namn = input.next();
    K[antalHandelser].setNamn(namn); //Finns det nått på plats 0 i arrayn?

 //Antal händelser har du satt till noll i din konstruktor 
 //(btw. så behöver du inte sätta den till noll. En icke satt int 
 //kommer alltid att defaultas till noll.

K[0] antar att det finns ett "kvitto" instansierad på första platsen i din array, men det finns ingen där. Därför får du en null pointer är min gissning. Men jag har bara tittat på koden lite fort, jag har inte kört den så jag kan ha fel. Sen försöker du utföra "null.setNamn(namn)" praktiskt taget. Detta går inte, därför kastar programmet en nullpointerexception.

En array används om du har ett fixerat antal av x-antal objekt. Vill du dynamiskt lägga till och ta bort saker så bör du använda dig av en arraylist istället. Men detta kanske är en skoluppgift där du ska använda arrayer. Det känns som en skoluppgift.

Btw. i javasyntax så ska inte första bracket "{" börja på ny rad. Det är C# och C++. I Java börjar dom på samma rad:

Kod:
public void WrongWay()
{
    for (int i = 0; i < 0; i++) 
    {
        //wrong way
    }
}

public void RightWay() {
    for (int i = 0; i < 0; i++) {
        //right way
    }
}
Citera
2015-11-02, 15:28
  #7
Medlem
Tom.Of.Finlands avatar
Så min array K[] finns egentligen inte?
Hur gör jag så K[] finns?

K står för kvitto.
Citera
2015-11-02, 15:49
  #8
Medlem
Kod:
Kvitto[] k = new Kvitto[10];

innebär att du har skappat en array(en lista) med 10 tomma platser. I denna kan du lagra 10 kvitton.

Du har INTE skapat en lista MED 10 kvitton i.

Kod:
Kvitto[] k = new Kvitto[10];
k[0] = new Kvitto();

Du måste sedan skapa ett kvitto och sätta det på en plats i arrayen. Här ovan skapar jag ett kvitto och placerar det på första platsen i arrayen.

Vill du dynamiskt kunna lägga till och ta bort kvitton lite hur som helst så bör du använda dig av en ArrayList istället som är en dynamisk lista. En array brukar man använda när man vet sitt exakta antal. En arraylist använder man om listan kommer växa och minska dynamiskt.

Kod:
List<Kvitto> kvitton = new ArrayList<Kvitto>();
k.add(new Kvitto());

sen är "k" inte ett bra namn på en lista. Det säger inget om vad det är.

Läs på mer om arrayer så förstår du hur man använder dom.
Citera
2015-11-02, 17:04
  #9
Medlem
Tom.Of.Finlands avatar
Tackar!! Jesus!

Jag glömde att lägga in en for-loop i konstruktören som skapar nya platser! Så korkad jag är!
Citera
2015-11-03, 10:33
  #10
Medlem
Haha korkad är du nog inte, alla glömmer vi saker. Ett klassiskt fenomen är att man blir "kodblind" efter att man stirrat för länge på sin egna kod.

Hoppas det löste sig!
Citera

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Det är enkelt att registrera ett nytt konto

Bli medlem

Logga in

Har du redan ett konto? Logga in här

Logga in