static nested class

static nested class
H4
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 4 lata
  • Postów:107
0

Co nieco z C++ wiem, ale chcę przejść do Javy, i zacząłem od "Thinking in Java by Bruce Eckel"

Cudownie, doszedłem do tematu, gdzie autor przedstawia deklarację statycznych klas w taki sposób

Kopiuj
 
class StaticTest {
static int i = 47;
}

Otóż to nie działa, korzystam z najnowszych JDK, i może książka była przeznaczona do wersji 6, a nie 7, to mimo wszystko taka rzecz nie powinna raczej ulec zmianie...

To samo pisze tu:
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

Eclipse nałogowo nakazuje mi usuwanie static, i w przypadku kombinowania - wielu innych fragmentów kodu, które po komentarzach w sieci na pewno są dobre

Nie wiem, może Eclipse przerywa kompilacje przez warningi?

W każdym razie, jak deklarować zmienne statyczne w klasie osadzonej?

"The field i cannot be declared static in a non-static inner type, unless initialized with a constant expression"

edytowany 1x, ostatnio: Hell4Ge
Olamagato
To nie jest deklaracja statycznej klasy, ale statycznego pola.
Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 2 godziny
0

Podaj kod który ci nie działa.

Edit:
Uściślając: podaj minimalny niekompilujący się kod, który obrazuje twój problem, a w którym do skompilowania wystarczy usunięcie modyfikatora static tak jak to Eclipse sugeruje.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 1x, ostatnio: Wibowit
PE
  • Rejestracja:ponad 19 lat
  • Ostatnio:prawie 12 lat
0

tu chyba chodzi o coś takiego

Kopiuj
 
public class A {

    class B{
        static int i = 5;
    }
}

modyfikator static jest niedozwolony w klasach wewnętrznych
ALE

Kopiuj
 
public class A {

    static class B{
        static int i = 5;
    }
}

ponieważ klasa B jest w takim wypadku statyczna (zagnieżdżona)

Edit:
http://lambda.univ.rzeszow.pl/kb/java/inner/testy.htm


pecet
edytowany 2x, ostatnio: pecet
Wibowit
W sumie jak dla mnie to to jest dość sztuczne ograniczenie.
Olamagato
  • Rejestracja:ponad 16 lat
  • Ostatnio:30 dni
  • Lokalizacja:Polska, Warszawa
  • Postów:1058
1

Przykład, który przytaczasz pochodzi ze strony 80 - przed rozdziałem "Twój pierwszy program w Javie", a klasy zagnieżdżone zaczynają się od strony 310.
Twój problem polega na tym, że zdefiniowanie klasy w klasie jest w C++ domyślnie klasą zagnieżdżoną, która nie ma nic wspólnego z klasą rodzica poza zasięgiem nazw. W Javie zdefiniowanie klasy w klasie daje klasę wewnętrzną - twór, który w C++ nie istnieje. Obiekt takiej klasy istnieje tylko wtedy kiedy istnieje obiekt klasy nadrzędnej, więc pola statyczne w takich klasach nie mogą istnieć za wyjątkiem zainicjowanych pól static final (np. static final String DEATH="Aaaaaa...."). Dlatego IDE każe Ci z takich pól wyrzucać modyfikator static. Alternatywnie możesz dać static final i inicjator, co zamknie plucie się IDE.
Aby zrobić z takiej klasy wewnętrznej klasę zagnieżdżoną, trzeba dodać modyfikator static. Jeżeli go dodasz, to z tworzeniem pól statycznych dowolnego rodzaju nie ma żadnego problemu.
Kiedy JVM ładuje klasę, to wszystkie elementy statyczne są opracowywane właśnie wtedy, natomiast niestatyczne dopiero podczas tworzenia obiektu klasy (załadowanej i już zarejestrowanej). Dlatego klasy wewnętrzne, które są niestatyczne nie mogą zawierać elementów statycznych bo te musiałyby istnieć zanim klasa wewnętrzna mogłaby zostać załadowana.
To co pisze na tej stronie o dostępie do pól i metod statycznych jest trochę nieaktualne. Otóż dostęp do tych elementów przez obiekt, czyli egzemplarz klasy jest już niezalecany i jest w IDE traktowany jako ostrzeżenie. Obecnie z wszystkich elementów statycznych korzysta się wyłącznie poprzez nazwę klasy, w której są zawarte. A więc

Kopiuj
public class External
{
	private class Internal
	{
		private static final CONST = 5;
	}
	//...
	private static class Nested
	{
		private static int CONST; //to nie jest prawdziwa stała, lecz zmienna "klasowa"
		//...
		CONST = 42;
		//...
		
	}
	//...
	private Internal internal = new Internal(); //pole niestatyczne
	private static Internal INTERNAL = new Internal(); //error
	private Nested nested = new Nested(); //pole niestatyczne
	private static Nested NESTED = new Nested(); //pole statyczne
	//...
	{
		//...
		int a = Nested.CONST; //dobrze
		int b = new Nested().CONST; //warning
		int c = new External().internal.CONST; //dobrze
		Nested d = External.NESTED; //dobrze
		int e = External.NESTED.CONST; //dobrze
		//...
	}
}

Jeżeli ktoś komuś coś, ewentualnie nikt nikomu nic, to właściwie po co...?
edytowany 4x, ostatnio: Olamagato
Azarien
ale porąbane...
PE
  • Rejestracja:ponad 19 lat
  • Ostatnio:prawie 12 lat
0

to powinno zobrazować różnice i zalety stosowanie tych rodzajów

Kopiuj
 
import java.util.LinkedList;
import java.util.List;

public class ClassExternal<V1 extends ClassExternal.Internal, V2 extends ClassExternal.Nested> {//genetyczne

    private int i = 5;
    private static int k = 5;
    private List<Internal> internals = new LinkedList<>();//powiązanie 1 instancja klasy zewnętrznej = wiele instancji klas wewnętrznych
    private List<Nested> nesteds = new LinkedList<>();

    public ClassExternal() {
        internals.add(new Internal());
        internals.add(new Internal());
        nesteds.add(new Nested(this));
        nesteds.add(new Nested(this));
    }

    public static void main(String[] args) {
        //Klasa
        ClassExternal ce = new ClassExternal();
        //Interfejs
        InterfaceExternal ie = new InterfaceExternal() {
        };
        //klasa zagnieżdżona (statyczna)
        //może istnieć niezależnie od klasy zewnętrznej
        ClassExternal.Nested cen = new ClassExternal.Nested(ce);
        InterfaceExternal.Nested ien = new InterfaceExternal.Nested(ie);
        
        //nieistnieje bez klasy zewnętrznej
        //InterfaceExternal.Internal iei = new InterfaceExternal.Internal();
    }

    public <T extends Internal> T getInternal(Class<T> clazz) {
        return (T) new Internal();
    }

    public <T extends Nested> T getNested(Class<T> clazz) {
        return (T) new Nested(this);
    }

    public Internal getInternal2() {
        return new Internal();
    }

    public Nested getNested2() {
        return new Nested(this);
    }

    //możliwość tworzenia w metodach statycznych
    public static <T extends Nested> T getStaticNested(Class<T> clazz, ClassExternal external) {
        return (T) new Nested(external);
    }

    public static Nested getStaticNested(ClassExternal external) {
        return new Nested(external);
    }

    private void prywatna() {
    }
    
    private static void prywatna2() {
    }

    void external() {
        Internal i = internals.get(0);
        Nested n = nesteds.get(0);

        //dostęp do zmiennych prywatnych/chronionych      
        i.i = 6;
        n.i = 6;//ale brak do statycznych

        //dostęp do metod prywatnych/chronionych  
        i.prywatna();
        n.prywatna();
    }

    public class Internal {

        private int i = 5;

        public Internal() {
        }

        private void prywatna() {
        }

        void external() {
            //dostęp do zmiennych prywatnych/chronionych
            ClassExternal.this.i = 6;//powiązanie 1 instancja klasy zewnętrznej = wiele instancji klas wewnętrznych
            ClassExternal.k = 6;

            //dostęp do metod prywatnych/chronionych 
            ClassExternal.this.prywatna();
            ClassExternal.prywatna2();
        }
    }

    public static class Nested {

        private static int k = 5;
        private int i = 5;
        private ClassExternal external;

        public Nested(ClassExternal external) {
            this.external = external;
        }

        private void prywatna() {
        }

        void external() {
            //dostęp do zmiennych prywatnych/chronionych
            external.i = 6;//tylko przez konkretny obiekt
            ClassExternal.k = 6;

            //dostęp do metod prywatnych/chronionych 
            external.prywatna();
            ClassExternal.prywatna2();
        }
    }
}
Kopiuj
public interface InterfaceExternal {

    //możliwość tworzenia w interfejsach
    //wszystkie klasy są statyczne
    class Nested {

        static int i = 5;
        InterfaceExternal external;

        public Nested(InterfaceExternal external) {
            this.external = external;
        }

        void external() {
        }
    }
}


pecet
Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 2 godziny
0

Dlatego klasy wewnętrzne, które są niestatyczne nie mogą zawierać elementów statycznych bo te musiałyby istnieć zanim klasa wewnętrzna mogłaby zostać załadowana.

Nie rozumiem tego zdania. Z twojego wywodu wynika, że dodanie final do statica w klasie wewnętrznej powoduje, że kompilacja się powodzi. Czemu akurat final ratuje sprawę?

Moim zdaniem jest to dość sztuczne ograniczenie, no chyba, że ułatwia to pisanie JVMa (tylko znowu pytanie, dlaczego?).


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
PE
  • Rejestracja:ponad 19 lat
  • Ostatnio:prawie 12 lat
0

modyfikator

  • static - oznacza że zmienna jest globalna w danej przestrzeni klasy
  • final - oznacza że zmienna jest stałą

połączenie static i final tworzy stałą globalną w danej przestrzeni klasy


pecet
Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 2 godziny
0

Ameryki nie odkryłeś, ani na moje pytanie nie odpowiedziałeś.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
Olamagato
  • Rejestracja:ponad 16 lat
  • Ostatnio:30 dni
  • Lokalizacja:Polska, Warszawa
  • Postów:1058
0

@Wibovit
Modyfikator final ratuje sprawę ponieważ zmienna staje się stałą wbitą do bytecodu. Jest to wtedy taka sama wartość w kodzie jak stała 5 czy 'a' - tyle, że nazwana. Klasa wewnętrzna jest jakby "podwłasnością" zewnętrznej, ale jest tak implementowana, że jej pola i metody istnieją tak naprawdę na poziomie klasy zewnętrznej aby mogły mieć pełny dostęp do wszystkich jej pól i metod. Gdyby klasy wewnętrzne zaimplementowano tak jak klasy zagnieżdżone (statyczne), to wtedy nie mogłyby mieć (niejawnego) dostępu do wszystkich pól i metod klasy zewnętrznej. Z drugiej strony ponieważ może istnieć tylko jeden blok statyczny dla każdej klasy na poziomie zewnętrznym, więc klasy wewnętrzne nie mogą mieć takiego bloku - i tu leży powód dlaczego nie mogą mieć komponentów statycznych. W czasie projektowania był to pewnie wybór "coś za coś". Jednak ponieważ klasy zagnieżdżone również istnieją, to nie jest to bardzo bolesne bo ma się wybór czy klasa niższego poziomu ma mieć takie własności oraz ograniczenia czy ich nie mieć.


Jeżeli ktoś komuś coś, ewentualnie nikt nikomu nic, to właściwie po co...?
edytowany 2x, ostatnio: Olamagato
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)