Archief - [ALG][JAVA] Unsafe operation vermijden

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

/\quila

Legacy Member
Hoi,

Ik heb volgende klasse geschreven, maar hij geeft een unsafe operation warning. Het kan dus compileren, maar ik zou de warning toch liever niet zien.
De fout zit hem in de Vector en iterator. Vector bevat objecten van klasse TekenObject, iterator geeft een object terug zodoende dat je het objecttype moet gaan specifiëren. Bestaat er andere oplossing zodoende dat de warning niet voorkomt?

Code:
import java.awt.*;
import java.util.Vector;
import javax.swing.*;
import java.awt.Graphics;
import java.util.*;

public class TekenCanvas extends Canvas 
{   
    public TekenCanvas()
    {
        super();
        TekenObjecten = new Vector();
    }

    public void paint(Graphics g)
    {
    }
    
    public void teken(String naam, int[] x, int[] y, Color kleur) {
        TekenObject tekenObject = new TekenObject(naam, x, y,kleur);
        TekenObjecten.addElement(tekenObject);
        
        Graphics g = getGraphics();
        g.setColor(tekenObject.getTekenKleur());
        g.fillPolygon(tekenObject.getXen(),tekenObject.getYen(),tekenObject.getAantal());
    }

/*******************
 * Warningmelding door : *
 ******************/ 

    public void verwijder(String naam) {
        for(Iterator i=TekenObjecten.iterator();i.hasNext();) {
            TekenObject getekendObject = (TekenObject)i.next();
            if(getekendObject.getNaam().equals(naam)) {
                TekenObjecten.remove(i.next());
            }
        }
    }
    
    public Vector<TekenObject> TekenObjecten;
}

WHiSPy

Legacy Member
Waarom krijgt ge die warning? Omdat gij met 'n reference naar 't object dat nog in uw collection zit bezig zijt. Ge kunt eventueel de suppresswarning annotation (ik zie door uw gebruik van generics dat ge op java 5 bezig zijt) die warning proberen te onderdrukken.

Slicer

Legacy Member
Code:
    public void verwijder(String naam) {
        for(Iterator i=TekenObjecten.iterator();i.hasNext();) {
            TekenObject getekendObject = (TekenObject)i.next();
            if(getekendObject.getNaam().equals(naam)) {
                TekenObjecten.remove(i.next());
            }
        }
    }

mm, ben ik het of verwijderd die code nu het object dat NA het gevonden object zit? (eerste keer i.next () geeft je het object met zelfde naam en de volgende keer i.next () geeft het volgende object, dus niet het object dat je wilt verwijderen).

De warning is inderdaad simpelweg een waarschuwing dat je een object verwijderd waarmee je aan het werken bent, maar in de api zit er daar in oplossing voor:

Code:
    public void verwijder(String naam) {
        for(Iterator i=TekenObjecten.iterator();i.hasNext();) {
            TekenObject getekendObject = (TekenObject)i.next();
            if(getekendObject.getNaam().equals(naam)) {
                i.remove ();
            }
        }
    }

Iterator heeft een remove actie die het laatste gereturnde object (via i.next () dus) verwijderd. Dan krijg je normaal geen waarschuwing meer.

/\quila

Legacy Member
Ja, ik zat inderdaad fout met die i.next(), je oplossing heeft ook het gewenste resultaat.

Ik sta nu voor een ander probleem, als ik volgende code toevoeg aan deze klasse, krijg ik telkens een NullPointerException. Ik zit der al op te zoeken van vlak na de vorige fout, maar vind het van geen kanten.

Code:
    public Vector listGetekendeObjecten(){
        Vector <String>getekendeObjecten = new Vector();
        for(Iterator i = TekenObjecten.iterator(); i.hasNext();) {
            TekenObject getekendObject = (TekenObject)i.next();
            String naamGetekendObject = getekendObject.getNaam();
            getekendeObjecten.add(naamGetekendObject);
        }
        return getekendeObjecten;
    }

De bedoeling is om uit de lijst met de TekenObjecten (die allemaal String naam, int[] x, int[] y, ... hebben) alle namen te halen, en dat te steken in een apparte vector.

sys4096

Legacy Member
Ge krijgt die warning omdat ge een remove doet uit uw Vector. Als je de lijst aan het doorlopen bent via een iterator MOET ge het gewenste object wissen via de iterator.

En inderdaad, 2 keer een .next() in uw loop is ook fout. Dan wist ge het object NA het object dat ge eigenlijk wou wissen.

killgore

Legacy Member
geeft die laatste code zelf de fout (bij aanroep) of gewoon het toevoegen (zal wel eerste zijn, ma kom). Kzie ook nie onmiddelijk de fout. Kan ook java bug zijn ffcourse.

Daarnaast: beke consistente naamgeving aub (variabelen beginnen met KLEINE letter :p).

edit: geef de code van TekenObject eens :).

/\quila

Legacy Member
killgore zei:
geeft die laatste code zelf de fout (bij aanroep) of gewoon het toevoegen (zal wel eerste zijn, ma kom). Kzie ook nie onmiddelijk de fout. Kan ook java bug zijn ffcourse.

Daarnaast: beke consistente naamgeving aub (variabelen beginnen met KLEINE letter :p).

edit: geef de code van TekenObject eens :).

Bij aanroepen van de code geeft hij fout. Dit stukje wordt gebruikt om een dropdownmenu te voorzien van elementen. Bij het aanmaken van dropdown geeft hij de nullpoint.
Heb naamgeving ook veranderd, zal een typfout geweest zijn (al meer als 10u hier mee bezig).

Code:
        jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(tekenCanvas.listGetekendeObjecten()));


TekenObject:
Code:
import java.awt.Color;

public class TekenObject
{

/*********
* VELDEN *
**********/
    private String $naam;           // de naam van dit object
    private int $aantal;            // het aantal hoekpunten van dit object
    private int[] $xen;             // de x-coordinaten van de hoekpunten
    private int[] $yen;             // de y-coordinaten van de hoekpunten
    private Color $tekenKleur;      // de kleur waarin het object op het scherm moet komen

/**************
* CONSTRUCTOR *
***************/   
    public TekenObject(String naam, int[] x,int[] y,Color c)
    {
        setNaam(naam);
        setXen(x);
        setYen(y);
        setKleur(c);
        setAantal(x.length);
    }

/**********
* SETTERS *
***********/     
    private void setNaam(String naam)   { $naam = naam; }    
    private void setAantal(int aantal)  { $aantal = aantal; }    
    private void setXen(int[] xen)      { $xen = xen; }
    private void setYen(int[] yen)      { $yen = yen; }    
    private void setKleur(Color c)      { $tekenKleur = c;}

/**********
* GETTERS *
***********/       
    public String getNaam()             { return $naam;}
    public int getAantal()              { return $aantal;}
    public int[] getXen()               { return $xen;}
    public int[] getYen()               { return $yen;}
    public Color getTekenKleur()        { return $tekenKleur;}    
    
}

.Acku.

Legacy Member
Ik neem aan dat ofwel uw tekenCanvas of jComboBox1 null is, of
String naamGetekendObject = getekendObject.getNaam();
een getekendObject null is

sys4096

Legacy Member
Kunt ge misschien eens zeggen in welke regel ge juist die nullpointer exception krijgt ? Is altijd handig om weten. En de relevante stukken sourcecode.

killgore

Legacy Member
.Acku. zei:
Ik neem aan dat ofwel uw tekenCanvas of jComboBox1 null is, of
String naamGetekendObject = getekendObject.getNaam();
een getekendObject null is
Da zou geen fout mogen geven dan toch, dan steekte gewoon null in da string object en later een null-object in uw string vector?
ik kan compleet niet inzien wat er fout is aan die code ... .

wat wel kan is da uw lijst leeg is en uw combo-box probleem geeft.

killgore

Legacy Member
.Acku. zei:
Je kan niet getNaam() doen op een getekendobject die null is.
ah, idd, kd8 da ge het op de return waarde had, niet goed gelezen, my bad :(.

if(...!=null dus toevoegen, moete eigenlijk altijd doen als ge referentie variabelen van ergens ophaalt of meekrijgt als argument.
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan