Идентификатор на грешки в хеш таблица на Java се очаква и нелегално начало на тип?

Предполага се, че това е част от прост интерпретатор с няколко ключови думи, които превърнах в различни класове. Програмата трябва да итерира ArrayList, да токенизира низовете и да ги анализира в KEYWORD + инструкции. Използвам hashmap, за да картографирам всички тези ключови думи към интерфейс, който има класове, където се извършва останалата част от обработката. В момента тествам един от тези класове ключови думи, но когато се опитам да компилирам, компилаторът извежда съобщения „очакван идентификатор“ и „незаконен старт на типа“. Редът, извеждащ всички съобщения за грешка, е ред 18. Къде кодът става нестабилен? Не мога да кажа, тъй като никога преди не съм използвал HashTable. Благодаря за помощта!

import java.util.*;

public class StringSplit
{
interface Directive //Map keywords to an interface
{
    public void execute (String line);
}
    abstract class endStatement implements Directive
    {
        public void execute(String line, HashMap DirectiveHash)
        {   
            System.out.print("TPL finished OK [" + " x lines processed]");
            System.exit(0);
        }
    }
    private Map<String, Directive> DirectiveHash= new HashMap<String, Directive>();
    DirectiveHash.put("END", new endStatement());

    public static void main (String[]args)
    {
        List <String> myString= new ArrayList<String>();
        myString.add(new String("# A TPL HELLO WORLD PROGRAM"));
        myString.add(new String("STRING myString"));
        myString.add(new String("INTEGER myInt"));
        myString.add(new String("LET myString= \"HELLO WORLD\""));
        myString.add(new String("PRINTLN myString"));
        myString.add(new String("PRINTLN HELLO WORLD"));
        myString.add(new String("END"));


        for (String listString: myString)//iterate across arraylist
        {   
                String[] line = listString.split("[\\s+]",2);
                for(int i=0; i<line.length; i++)
                {
                    System.out.println(line[i]);
                    Directive DirectiveHash=DirectiveHash.get(listString[0]);
                    DirectiveHash.execute(listString);

                }

        }

    }
}

person Luinithil    schedule 11.01.2012    source източник
comment
Кой ред дава грешка при компилиране? Това вероятно е добра отправна точка.   -  person Michael Myers    schedule 11.01.2012
comment
Добре, значи това е ред 18. Кой ред е ред 18? (Да, мога да разчитам. Само се опитвам да отбележа, че поставянето на цялата ви програма, когато вече знаете кой ред се проваля, е донякъде контрапродуктивно.)   -  person Michael Myers    schedule 11.01.2012
comment
Горещо препоръчвам да използвате конвенции за именуване на Java: oracle.com/technetwork/java/codeconvtoc -136057.html   -  person jbindel    schedule 11.01.2012


Отговори (5)


За да преодолеете текущата грешка на компилатора, ще трябва да поставите извикването DirectiveHash.put("END", new endStatement()); вътре в някакъв блок. Ако го искате в инициализатора на екземпляра, опитайте това:

{ DirectiveHash.put("END", new endStatement()); }

person jbindel    schedule 11.01.2012
comment
Имате друга грешка в това, че класът endStatement не прилага public void execute (String line);, защото го дефинирате с допълнителен параметър. Също така няма да можете да създадете екземпляр на abstract клас с new endStatement(), защото е абстрактен. - person jbindel; 11.01.2012

Имената на вашите променливи трябва да започват с малка буква. DirectiveHash се използва като име на променлива и имената на класове/интерфейси трябва да започват с главни букви.

person Dan Hardiker    schedule 11.01.2012
comment
Не, DirectiveHash е само променлива. Directive е името на интерфейса. - person Michael Myers; 11.01.2012
comment
И това все още създава доста проблеми... моята точка 5 по-долу. - person wmorrison365; 11.01.2012

Вашият DirectiveHash.put("END", new endStatement()); трябва да е в някакъв метод. И тъй като вашият клас endStatement е абстрактен, той не може да бъде инициализиран с помощта на new

person Gaurav    schedule 11.01.2012

Няколко въпроса, за да бъда честен:

  1. endStatement не прилага правилно директивата, тъй като подписите на метода #execute не съвпадат.

  2. Не можете да направите следното, тъй като endStatement е абстрактен (не може да бъде инстанциран директно).

    DirectiveHash.put("END", new endStatement());
    
  3. Това не може да се направи извън блок или метод. обикновено бихте използвали конструктор:

    DirectiveHash.put("END", new endStatement());
    
  4. Всъщност никога не инициализирате DirectiveHash в main. Имайте предвид, че това е променлива на екземпляр на класа, а main е статичен метод. За да може main да използва DirectiveHash, той трябва да има екземпляр на клас StringSplit, от който да го получи.

  5. Следващият ред е малко подвеждащ, тъй като присвоявате името на променливата на екземпляра да бъде същото като името на класа. Легално, но адски объркващо за четене и наистина лоша идея. Всъщност в този случай е по-обезпокоително, тъй като не сте инстанциирали своя DirectoryHash в #main. Така че ivar directoryHash (за да спестим объркване) се настройва да бъде директива и последващото ни извикване на „DirectiveHash=DirectiveHash.get(...)“ става повредено, тъй като предполага извикване на Directive#get, която не съществува.

    Directive DirectiveHash=DirectiveHash.get(listString[0]);
    
  6. Следният ред е невалиден, тъй като „listString[0]“ не е валиден. Декларирахте listString като String във вашия for() цикъл - не за масива.

    Directive DirectiveHash=DirectiveHash.get(listString[0]);
    
  7. Вашето изписване с главни букви трябва да бъде по-строго... използвайте начални главни букви за класове и интерфейси и малки инициали за имена на методи и променливи.

Е, това беше като едно от интервютата, с които сте компилаторът. Виждам, че някои вече са били публикувани, така че съжалявам за това. Може и да съм пропуснал някои...

Може да се наложи да прочетете някои от тези проблеми:

  • Конструктори
  • Статични методи срещу методи на екземпляри
  • Внедряване на интерфейси
  • Цел/използване на абстрактни класове
person wmorrison365    schedule 11.01.2012

опитвате се да създадете абстрактен клас. абстрактните класове не могат да бъдат създадени чрез оператора new.

може би трябва да разширите класа endStatement (и също да го преименувате на EndStatement) и да предоставите конкретна реализация за него

person jere    schedule 11.01.2012