Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Error:(52, 22) java: non-static variable this cannot be referenced from a static context

Aktivity
Avatar
ra3sk
Člen
Avatar
ra3sk:17.4.2017 16:24

Zdar, rozhodol som sa trochu zabrdnúť do Javy. Skúšam si len prácu s objektom a zrazu som dostal tento Error:(52, 22) java: non-static variable this cannot be referenced from a static context. Neviem prečo, lebo by som nechcel aby niečo z môjho kódu bolo statické. Prosím o vysvetlenie prečo pri tomto konkrétnom kóde vznikol problém. Predom ďakujem všetkým čo si nájdu čas a poradia.

public class Main {

    public class Clovek{
        private int age;
        private String name;
        private String location;
        private int salary;

        public Clovek(int age, String name, String location, int salary){
            this.age = age;
            this.name = name;
            this.location = location;
            this.salary = salary;
        }

        public int getAge(){
            return this.age;
        }

        public int getSalary(){
            return this.salary;
        }

        public String getName(){
            return this.name;
        }

        public String getLocation(){
            return this.location;
        }

        public void changeName(String newName){
            this.name = newName;
        }

        public void beOlder(){
            this.age = this.age++;
        }

        public void changeLocation(String newLocation){
            this.location = newLocation;
        }

        public void topUpSalary(int raise){
            this.salary += raise;
        }

    }


    public static void main(String[] args) {
        Clovek Jan = new Clovek(23,"Ján","Bratislava", 40000);
        System.out.println(Jan.getAge());
    }
}
 
Odpovědět
17.4.2017 16:24
Avatar
Odpovídá na ra3sk
Matúš Petrofčík:17.4.2017 16:28

Skús triedu Clovek nastaviť na private a static ;)

public class Main {

    private static class Clovek{
        // ...
    }


    public static void main(String[] args) {
        Clovek Jan = new Clovek(23,"Ján","Bratislava", 40000);
        System.out.println(Jan.getAge());
    }
}
Nahoru Odpovědět
17.4.2017 16:28
obsah kocky = r^2 ... a preto vlak drnká
Avatar
ra3sk
Člen
Avatar
Odpovídá na Matúš Petrofčík
ra3sk:17.4.2017 16:31

Hej, to by fungovalo. V podstate mi to aj IntelliJ ponúkol, len neviem prečo to tak má byť. Prečo má byť trieda static?

 
Nahoru Odpovědět
17.4.2017 16:31
Avatar
Odpovídá na ra3sk
Matúš Petrofčík:17.4.2017 16:37

Skúsil som vyhľadať v Googli: "Static nested class in Java" a toto mi vypísalo:

A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class.
...
Note: A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.

http://stackoverflow.com/…3521/3054996

Nahoru Odpovědět
17.4.2017 16:37
obsah kocky = r^2 ... a preto vlak drnká
Avatar
Odpovídá na ra3sk
Matúš Petrofčík:17.4.2017 16:46

Tuto je možno lepšie vysvetlenie: http://stackoverflow.com/a/70358/3054996

Predchádzajúca odpoveď nič moc nevysvetľuje :D sry

Ak som to pochopil správne, tak statickú vnorenú triedu môžeš použiť aj bez inštancie objektu, ale obyčajnú vnorenú triedu iba pomocou nejakej inštancii objektu.

Ak je vnorená trieda static:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

Ak je vnorená trieda obyčajná, nestatická, najprv musíš vytvoriť vonkajšiu triedu a až tak tú vnorenú:

OuterClass outerObject = new OuterClass();
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Editováno 17.4.2017 16:47
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
17.4.2017 16:46
obsah kocky = r^2 ... a preto vlak drnká
Avatar
Jan Vargovský
Tvůrce
Avatar
Odpovídá na ra3sk
Jan Vargovský:17.4.2017 17:05

Zkus:

Main.Clovek Jan = new Main.Clovek(23,"Ján","Bratislava", 40000);
 
Nahoru Odpovědět
17.4.2017 17:05
Avatar
pocitac770
Tvůrce
Avatar
Odpovídá na ra3sk
pocitac770:17.4.2017 17:17

Každopádně, možná bude tím hlavním problémem to, že jsi zde vytvářel vnořenou třídu do třídy main. Podle mě jsi ani toto dělat nechtěl, protože vnořené třídy se normálně dávají jako podtřídy nějakých objektů, jejich např. vlastnosti, takže zde to moc návrhovému vzoru nesedí. Asi jsi chtěl vytvořit zkrátka novou třídu, ale nedát ji do souboru zvlášť (což je normálně standartní postup, ale jde to i takto).
V tom případě by jsi blok "public class Clovek{......}" musel napsat mimo block "public class Main{....}", tzn. až na konec za poslední závorku, v tu chvíli se z toho stává normální třída.
Pokud se mýlím, tak mě klidně zlynčujte, jen jsem zkusil trochu dedukce :D

Editováno 17.4.2017 17:17
 
Nahoru Odpovědět
17.4.2017 17:17
Avatar
ra3sk
Člen
Avatar
ra3sk:17.4.2017 17:22

Díky moc. Pomohlo mi snaď všetko, čo sem bolo napísané, ale bohužiaľ len 1 odpoveď môže byť označená za riešenie. pocitac770 aj ty mas pravdu a vysvetlil si mi to ako lajkovi.

 
Nahoru Odpovědět
17.4.2017 17:22
Avatar
pocitac770
Tvůrce
Avatar
Odpovídá na Matúš Petrofčík
pocitac770:17.4.2017 17:29

Tak zkusím něco já.... Trochu jsem vymyslel několik situací, nemám to odzkoušeno, takže možná říkám blbosti...
Představme si vnořenou třídu jako normální atribut objektu. to hned pak začne vysvětlovat vše... :D
Pokud máme normální (ne-statickou) třídu A v normální třídě B, pak je ten atribut unikátní pro každý objekt. Proto se to chová, jako by se třída A inicializovala pro každou instanci třídy B. Co je důsledkem? Statické proměnné budou u každého objektu různé. Proto když chceme získávat nějaké statické atributy z třídy A, musíme je volat na INSTANCI třídy B.
Co když je třída A statická a třída B normální? Pak je to to samé, jako by se jednalo o statický atribut. Pro všechny instance třídy B je celá třída A společná, tudíž všechno z ní vypadá pro všechny instance stejně, tudíž se může volat normálně na třídě B, ne na instanci. Teď dotaz... Jde vnořená statická třída instancovat? Pokud ano, dosti by to vysvětlovalo (není statická vůči instancím třídy A, ale vůči třídě a instancím třídy B).
Po tomto si říká, jestli má vůbec nějaký smysl psát "static" před hlavní třídu, nebo spíše účinek, to doplňte sami, alespoň si tu dáme hodinu filosofování :D

 
Nahoru Odpovědět
17.4.2017 17:29
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 9 zpráv z 9.