Java modifierare. Åtkomstmodifierare

Låt oss först ta itu med åtkomstmodifierare. Det finns bara fyra av dem:

  • privat klassmedlemmar är endast tillgängliga inom klassen
  • paket-privat eller standard (standard) klassmedlemmar är synliga inuti paketet
  • skyddad klassmedlemmar är tillgängliga i paketet och i härledda klasser
  • offentlig klassmedlemmar är tillgängliga för alla

Under nedärvning är det möjligt att ändra åtkomstmodifierare mot STÖRRE synlighet.

Åtkomstmodifieraren för konstruktörer, metoder och fält kan vara vilken som helst, men med klasser och deras block är allt inte så enkelt. En klass kan bara vara antingen offentlig eller standard, och endast en offentlig klass kan vara i en fil. Ett block kan bara ha en modifierare - standard.

statiska, abstrakta och slutliga modifierare

Statisk

  • Gäller inre klasser, metoder, variabler och logiska block
  • Statiska variabler initieras vid klassladdningstid
  • Statiska variabler är desamma för alla objekt i klassen (samma referens)
  • Statiska metoder har bara tillgång till statiska variabler
  • Statiska metoder och variabler kan nås via klassnamnet
  • Statiska block exekveras vid klassladdningstid
  • Icke-statiska metoder kan inte åsidosättas som statiska
  • Lokala variabler kan inte deklareras som statiska
  • Abstrakta metoder kan inte vara statiska
  • Statiska fält serialiseras inte (endast vid implementering av det serialiserade gränssnittet)
  • Endast statiska klassvariabler kan skickas till en konstruktor med parametrar, anropade via ordet super(//parameter//) eller this(//parameter//)

Abstrakt

  • Gäller endast metoder och klasser
  • Abstrakta metoder har ingen metodkropp
  • Det är motsatsen till final: slutklass kan inte ärvas, abstrakt klass måste ärvas
  • En klass måste förklaras abstrakt om:
  1. den innehåller minst en abstrakt metod
  2. det ger inte implementering av nedärvda abstrakta metoder
  3. den tillhandahåller inte en implementering av metoderna för gränssnittet som den deklarerade att implementera
  4. det är nödvändigt att förbjuda skapandet av instanser av klassen

Slutlig

  • Fält kan inte ändras, metoder åsidosätts
  • Klasser kan inte ärvas
  • Denna modifierare gäller endast klasser, metoder och variabler (även lokala variabler)
  • Metodargument markerade som final är skrivskyddade, försök att ändra kommer att resultera i ett kompileringsfel
  • Slutvariabler initieras inte som standard, de måste explicit tilldelas ett värde när de deklareras eller i konstruktorn, annars ett kompileringsfel
  • Om en slutlig variabel innehåller en referens till ett objekt kan objektet ändras, men variabeln kommer alltid att referera till samma objekt.
  • Detta gäller även för arrayer eftersom arrayer är objekt - en array kan ändras och en variabel kommer alltid att referera till samma array.
  • Om en klass förklaras som slutgiltig och abstrakt (ömsesidigt uteslutande) kommer ett kompileringsfel att uppstå
  • Eftersom en slutlig klass inte kan ärvas, kan dess metoder aldrig åsidosättas.
Konstruktör kan inte vara statisk, abstrakt eller slutgiltig

strictfp, transient, volatile, synkroniserade, infödda modifierare

Striktfp

  • Gäller metoder och klasser
  • Ger operationer på flytande och dubbla (flytande) tal enligt IEEE 754-standarden

Övergående

  • Gäller endast klassnivåvariabler (lokala variabler kan inte deklareras transienta)
  • Transienta variabler behöver inte vara slutgiltiga eller statiska.
  • Transienta variabler serialiseras inte

Flyktig

  • Används endast med variabler
  • Kan användas med statiska variabler
  • Används inte med slutvariabler - Värdet på en variabel som deklareras som flyktig, ändrad av en tråd, ändras asynkront för andra trådar
  • Används i flertrådiga applikationer

Synkroniserad

  • Gäller endast metoder eller delar av metoder
  • Används för att kontrollera åtkomst till viktiga delar av koden i flertrådade program

inföding

  • Används endast för metoder
  • Indikerar att metoden är skriven på ett annat programmeringsspråk
  • Klasser i Java använder många inbyggda metoder för att förbättra prestanda och tillgång till hårdvara
  • Det är möjligt att förråda/returnera Java-objekt från inhemska metoder
  • Metodsignaturen måste sluta med ";", lockiga klammerparenteser orsakar kompileringsfel

Funktioner i gränssnitt

  • Metoder är alltid offentliga och abstrakta, även om de inte deklareras
  • Metoder kan inte vara statiska, slutgiltiga, strictfp, infödda, privata, skyddade
  • Variabler är endast offentliga statiska slutgiltiga även om de inte deklareras
  • Variabler kan inte vara strictfp, inbyggda, privata, skyddade
  • Kan bara utöka ett annat gränssnitt, men inte implementera ett gränssnitt eller klass (implementer).

Att sätta ihop alla modifierare:

Klass

inre klass

Variabel

Metod

Konstruktör

Logisk block

offentlig

Ja

Ja

Ja

Ja

Ja

Inte

skyddad

Inte

Ja (förutom lokala och anonyma klasser)

Ja

Ja

Ja

Inte

standard

Ja

Ja

Ja

Ja

Ja

privat

Inte

Ja (förutom lokala och anonyma klasser)

Ja

Ja

Ja

Inte

slutlig

Ja

Ja (och för lokal variabel)

Ja

Inte

Inte

abstrakt

Ja

Ja (förutom anonyma klasser)

Inte

Ja

Inte

Inte

statisk

Inte

Ja (förutom lokala och anonyma klasser)

Ja

Ja

Inte

Ja

inföding

Inte

Inte

Inte

Ja

Inte

Inte

övergående

Inte

Inte

Ja

Inte

Inte

Inte

synkroniserad

Inte

Inte

Inte

Ja

Inte

Ja (endast som en del av en metod)

flyktig

Inte

Inte

Ja

Inte

Inte

Inte

striktfp

Ja

Ja

Inte

Ja

Inte

Inte

Modifieringsklass
Klassen Modifier kodar alla modifierare
används i typdeklarationer, i formuläret
konstanter:
ABSTRAKT, FINAL, GRÄNSSNITT, NATIVE,
PRIVAT, SKYDDAD, OFFENTLIG, STATISK,
STRIKT, SYBKRONISERAD, TRANSIDENT,
FLYKTIG.
Var och en av konstanterna motsvarar en begäranmetod för formuläret
isMod(int modifier) ​​(här är Mod en av ovanstående
förnamn, till exempel isPublic),
som returnerar sant om modifieraren
mod finns i typdeklarationen.

Tänk på ett exempel. Låt det finnas
fältdeklaration
offentlig statisk slutlig int s=10;
sedan returvärdet för metoden
getModifiers för motsvarande objekt
av fältklassen kommer att se ut
Modifierare.PUBLIC | Modifierare.STATISK |
Modifierare.FINAL
strictfp-modifieraren visas
konstant STRIKT.
Begäransmetoder kan användas i
följande formulär

Modifier.isPrivate(field.getModifiers());
detta motsvarar följande villkor
(field.getModifiers()&Modifier.PRIVATE)!=0
Fältklass
Field-klassen implementerar metoder
att begära information om
fälttyp, samt läs och ställ in den
menande.
Överväg några metoder i klassen Field
1. getType() - returnerar ett klassobjekt
Klass som motsvarar typen av det aktuella fältet.
Till exempel, för ett fält av typen int, får vi
int klass

2. Metoder ställ in och få - låter dig läsa
det aktuella värdet för fältet, samt ställ in ett nytt.
Tänk på ett exempel:
public static void printField(Objekt o,
Strängnamn) kastar
NoSuchFieldException,
IllegalAccessException(
field field = o.getClass().getField(name);
Kort värde = (Kort) field.get(o);
System.out.println(värde);
}
De där. get-metoden returnerar värdet som
hänvisar till motsvarande fält eller objekt
skalklass.
Ett exempel på hur man använder set-metoden ser ut så här:

public static void setField(Object o, String name,
kort nv) kastar
NoSuchFieldException,
IllegalAccessException(
Fältfält = o.getClass().getField(name) ;
field.set(o,new Short(nv));
}
För att lagra nv i fältet för detta objekt
omslagsklasser måste användas.
Det finns också metoder som ser ut
getPrimitiveType (t.ex. getInt) och
setPrimitiveType. Dessa metoder kan
använd för att ändra fält i en klass,
ha en primitiv typ. Till exempel,
field.setShort(o,nv);

Metodklass
Medel av metoden klass - låter dig få
fullständig information ang
deklarationer av metoder av en viss klass,
och ring dessa metoder om det behövs
sammanhanget för de givna objekten.
Tänk på metoderna i klassen Method.
1. public Class getReturnType() - returnerar
klassobjektet som motsvarar typen
värdet som returneras av den aktuella metoden.
Om istället för returen skriv in
metoddeklaration specificerad tjänst
ordet void, kommer metoden i fråga tillbaka
void.class objekt.

2. public Class getParameterTypes() - returnerar

parametrar som anges i deklarationen
nuvarande metod. Objekt läggs in i en array i
i den ordning som parametrarna är listade i
metoddeklaration. Om metoden inte gör det
parametrar, returneras en tom array.
3. public Class getExceptionTypes() - returnerar
en array av klassobjekt som motsvarar typerna
undantag som anges i förslaget
kastar deklaration av den aktuella metoden. Föremål
läggs in i arrayen i den ordning som
undantagstypsnamn listas i
metoddeklaration.

4. public Object invoke(Object onThis, Object args)
kastar IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
Anropar en metod som definieras av det aktuella objektet
Metod, i samband med ett onThis objekt med ett jobb
argumentvärdena som skickas av args-arrayen.
För icke-statiska metoder, valet av implementering
utförs baserat på den faktiska typen
objektet som anges av parametern onThis. För
statiska metoder påDetta accepteras inte under
uppmärksamhet och kan vara ogiltig.
Längden på args-matrisen måste matcha numret
parametrar i metoddeklarationen och arrayelementobjekttyperna måste kunna tilldelas
motsvarande typer av metodparametrar - in
annars kommer ett undantag att kastas
IIlegalArgumentException.

10.

Om som en del av ett definierat objekt
onDenna parameter, ingen typ, medlem
vilket är den nuvarande metoden,
ett undantag kastas
IllegalArgumentException.
Om värdet på onThis är null och metoden inte är det
statisk, kastar ett undantag som
NullpointerException.
Om utförandet av den anropade metoden
avslutas onormalt, kastas bort
ett undantag av typen InvocationTargetException.

11.

Tänk på ett exempel. Låt oss kalla medlen
reflektionsmetod returnerar str.indexOf(".", 8)
då har vi
Prova(
Сlass strClass = str.getClass();
Metod indexM = strClass.getMethod("indexOf",
new Class(string.class, int.class));
Objektresultat = indexM.invoke(str, nytt objekt (
".", nytt lnteger(8)));
return ((heltal)resultat).intValue();
}
catch (NoSuchMethodException e) ( …….. )
catch (invocationTargetException e) (…….. )
catch (illegalAccessException e) (……)

12.

Konstruktörsklass
För att skapa nya instanser (objekt)
typmetod kan användas
newInstance av Class-objektet,
motsvarande denna typ.
Metoden anropar konstruktorn utan argument,
ägs av typen och returnerar en referens
till ett nyskapat objekt av klassen Object,
som uttryckligen måste omvandlas till
önskad typ.
Tänk på ett exempel.

13.

statisk dubbeltestData = (0,3,1,3e-2, 7,9, 3,17);

Prova(
for(int arg = 0; arg< args.length; arg++){
Strängnamn = args;
Class classFor = Class.forName(name);
SortDubbel sorterare =
(SortDouble)classFor.newInstance();
SortMetrics metrics = sorter.sort(testData);
System.out.println(namn + ": " + mätvärden);
for(int i =0; i< testData.length; i++)
System.out.println(" " + testData[i]); ) )
catch(Undantag e) ( System.err.println(e); ) )

14.

newlnstance-metoden när den är felaktig
applikationen kan kasta ut en stor
antal olika undantagsobjekt
typer.
InstantiationException - om klass, objekt
som borde skapas, inte besitter
konstruktor utan argument, eller
definieras som abstrakt, eller in
verkligheten är ett gränssnitt,
eller utföra skapandet
objektet avbryts av någon annan
skäl.
IllegalAccessException - om klassen är antingen dess
konstruktor utan argument är inte tillgängliga.

15.

SecurityException - om den aktuella policyn
säkerheten förbjuder skapandet av nya objekt
ExceptionInInitializerError - kastas när
klassinitiering.
Det finns andra metoder definierade i Constructor-klassen.
public Сlass getParameterTypes()

motsvarande de typer av parametrar som
definieras i deklarationen från den nuvarande konstruktören.
public Class getExceptionTypes()
Returnerar en array av klassobjekt,
motsvarande de typer av undantag som
definieras i kastklausulen i deklarationen
nuvarande konstruktör.

16.

public Object newInstance(Object args)
kastar InstantiationException,
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
Använder konstruktorn som representeras av strömmen
ett konstruktorobjekt att skapa och initiera
ny instans av klassen, där konstruktorn
förklarade, med de angivna argumenten godkända.
Returnerar en referens till den nyskapade och
initierat objekt. args array längd
måste matcha antalet parametrar i
konstruktordeklaration och objekttyper för arrayelement måste kunna tilldelas
motsvarande typer av konstruktorparametrar -
annars kommer ett undantag att kastas
IllegalArgumentException.

17.

Tänk på ett exempel:
klassmin klass(
privat int a;
public Myclass(int k)(a=k;)
public int func(int a,int b)(retur a+b;)
}
allmän klass Main(
public static void main(String args)(
Prova(
Stringname="minklass";
Class mycl=Class.forName(name);
Klass d=(int.klass);
Konstruktör c=mycl.getConstructor(d);
Myclass ob=(Myclass)c.newInstance(new Object(
nytt heltal(10)));
System.out.println(ob.func(3,5)); )
catch(Undantag e)();
}}

18.

AccessibleObject-klassen
Fält-, konstruktörs- och metodklasserna är
härledd från AccessibleObject-klassen,
som gör det möjligt att tillåta eller
inaktivera kontroll av nivååtkomstflagga
språk som offentliga och privata.
Klassen AccessibleObject har metoder
1. public void setAccessible(boolesk flagga)
Ställer in objektets åtkomstflagga till
enligt argument värde: sant
betyder att objektet inte längre följs
åtkomstregler som fastställts på nivån
språk (och kommer alltid att vara tillgängligt), ett falskt
tvingar objektet att behålla det angivna
åtkomstnivå.
Om behörigheterna att ändra åtkomstflaggan
räcker inte, ett undantag kastas som
SecurityException

19.

2. offentlig statisk
void setAccessible(AccessibleObject array,
boolesk flagga)
Låter dig ställa in åtkomstflaggan
objekt som skickas som en array.
Om i färd med att bearbeta nästa
objekt ger ett undantag av typ
SecurityException, objekt lokaliserade
i arrayen tidigare, spara den nyuppsättning
åtkomstnivåvärden och alla andra
föremål förblir desamma.
3. public boolean isAccessible()
Returnerar det aktuella värdet för åtkomstflaggan
till föremålet

20.

Array klass
Klassen Array används för att skapa en array
medel för reflektion.
Två former av metoder används för att skapa arrayer
nyinstans.
public Object newInstance(Class compType, int length)
Returnerar en referens till en ny array av typen compType
given längd längd.
public Object newInstance(Class compType, int dim)
Returnerar en referens till en ny flerdimensionell array av typ
compType vars dimensioner ges av värdena
element i array-parametern dim.
Om matrisen är tom eller har en längd som är större än
tillåtet antal dimensioner (vanligtvis 255),

legalArgumentException.

21.

Tänk på exempel.
Exempel1. Låt oss bilda en array av typen byte
ba = (byte)
Array.newInstance(byte.class,13);
Detta är likvärdigt
ba = ny byte;
Exempel 2.
int dim = (4, 4);
dubbelmatris =(dubbel)
Array.newInstance(double.class, dims);
Detta är likvärdigt
dubbelmatris = ny dubbel;

22.

Klassen Array har get- och set-metoder.
Låt en matris xa med värden av typen int ges; sedan
uttryck xa[i] kommer att matcha:
Heltal n=Array.get(xa, i)
Du kan tilldela ett värde till ett matriselement så här:
xa[i] = 23; är det samma som
Array.set(xa, i, nytt heltal(23));
Paketklass
Att anropa getPackage-metoden för klassen Class tillåter
få ett objekt av klassen Package som innehåller
Beskrivning av paketet som innehåller
klass (Själva paketklassen finns i paketet
java.lang).
Metoden getName() för paketobjektet returnerar
det fullständiga namnet på det aktuella paketet.

23.

Fullmaktsklass
Proxy-klassen låter dig skapa dynamiskt
klasser som implementerar en eller flera
gränssnitt.
Anta att vi har klass A,
implementera vissa gränssnitt.
Java-maskinen vid körning kan
generera en proxyklass för den givna
klass A, dvs. en klass som
implementerar alla gränssnitt i klass A, men
ersätter att anropa alla metoder av dessa
gränssnitt för att anropa anropsmetoden,
gränssnitt InvocationHandler, för
som du kan definiera din
genomförande.

24.

En proxyklass skapas med ett metodanrop
Proxy.getProxyClass som tar en ClassLoader och
en uppsättning gränssnitt (gränssnitt), och returnerar ett objekt
klass java.lang.Klass som är laddad med
av den godkända ClassLoader och implementerar den godkända arrayen
gränssnitt.
Det finns ett antal begränsningar för de angivna parametrarna:
1. Alla objekt i gränssnittsmatrisen måste vara
gränssnitt. De kan inte vara klasser eller
primitiver.
2. Det kan inte finnas två identiska i gränssnittsarrayen
föremål.
3. Alla gränssnitt i gränssnittsmatrisen måste vara
laddas av ClassLoader som skickas till metoden
getProxyClass.
4. Alla icke-offentliga gränssnitt måste definieras
i samma paket, annars genererad proxyklass
kan inte genomföra dem alla.

25.

5. Inga två gränssnitt kan ha
metod med samma namn och
parametersignatur, men med olika
returtyper.
6. Längden på gränssnittsarrayen är begränsad
65535 gränssnitt. Ingen Java-klass
kan inte implementera mer än 65535
gränssnitt.

26.

Dynamiska proxyegenskaper
1. Fullmaktsklassen är offentlig, förutsatt
slutlig modifierare och är inte abstrakt.
2. Standard proxyklassnamn är inte
definieras, men börjar med proxy. Allt
namnutrymme som börjar med proxy
reserverad för proxyklasser
(Detta krävs inte i de senaste versionerna av Java.)
3. Proxyklassen ärvs från
java.lang.reflect.Proxy.
4. Proxyklassen implementerar alla gränssnitt,
överförs vid tillkomsten, i ordningsföljd.

27.

5. Om proxyklassen implementerar en icke-offentlig
gränssnittet kommer det att genereras i det paketet,
som definierar detta mest icke-offentliga
gränssnitt. I allmänhet ett paket som
proxyklass odefinierad kommer att genereras.
6. Metod Proxy.isProxyClass returnerar sant för
klasser skapade med
Proxy.getProxyClass och för objektklasser,
skapat med Proxy.newProxyInstance och
falskt annars.
Denna metod används av delsystemet
Java-säkerhet och du måste förstå det för
en klass som helt enkelt ärvts från
java.lang.reflect.Proxy den kommer att returnera falskt.

28.

Egenskaperna för den skapade instansen av proxyklassen är följande:
1. Objektet för proxyklassen castas till alla gränssnitt,
passerade i gränssnittsarrayen. Om IDemo är en av
av de godkända gränssnitten, sedan operationsproxyinstansen av
IDemo kommer alltid att returnera sant, medan (IDemo) proxyoperation
kommer att sluta korrekt.
2. Statisk metod Proxy.getInvocationHandler
returnerar samtalshanteraren som skickades vid skapandet
instans av proxyklassen. Om överförs till detta
metodobjektet är alltså inte en instans av proxyklassen
ett undantag från IllegalArgumentException kommer att kastas.
3. Anropshanterarklassen implementerar gränssnittet
InvocationHandler, som definierar anropsmetoden,
med följande signatur:
public Object invoke(Object proxy, Method method,
Object args) kastar Throwable

29.

Tänk på ett exempel:
packagejavaapplication3;
gränssnittskonto(
dubbel getBalance();
void changeBalance(int summa);
tomgångsprocent (dubbel per);)
klass MyAccount implementerar konto(
privat dubbelbalans;
public MyAccount()( saldo=0.0; )
public double getBalance()( returnera saldo; )
public void changeBalance(int summa)(
saldo+=summa;)
offentliga tomrumsprocenter(dubbel per)(
saldo+=saldo*per/100; ); )

30.

klass MyAccountProxy implementerar
InvocationHandler(
privat konto ac;
public MyAccountProxy(Account acc)( ac=acc; )
offentligt statiskt konto newInstance(Konto da)(
returnera (konto)Proxy.newProxyInstance(
da.getClass().getClassLoader(),
da.getClass().getInterfaces(),
ny MyAccountProxy(da));
}

31.

public Object invoke(Objekt proxy,
metod metod, objekt args)
kastar Kastbar(
if(method.getName()=="procent")(
dubbel d=((Double)args).doubleValue();
om (d<0) d=0;
om(d>30) d=30;
args=ny dubbel(d);

annan(
return method.invoke(ac, args); )
}
}

32.

allmän klass Main(
public static void main(String args)(
MyAccountma=nytt MyAccount();
konto
a=(Konto)MyAccountProxy.newInstance(ma);
a.changeBalance(150);

a.procent(20);
System.out.println(a.getBalance());
a.procent(35);
System.out.println(a.getBalance());) )

33.

Laddar klasser
Runtime-systemet laddar klasser efter behov.
behovet av dem.
Funktionella funktioner för startprocedurer
klasser i huvudsak beror på
implementering av de virtuella Java-maskinerna, men i
de flesta fall för att hitta klasser,
adresserad av applikationen, men inte nedladdad
verkställande systemet tillämpas mekanismen
visar klasssökvägen.
För att skapa en applikation som kan
belastningsklasser på annat sätt än
tillhandahålls som standard, bör
använd ett objekt av klassen ClassLoader,
kunna få bytekoden för genomförandet av den önskade
klass och ladda den i körtiden
system.

34.

Klassen ClassLoader är en abstrakt klass.
För att skapa din egen klassladdare,
du måste skapa en klass som ärver från
ClassLoader och åsidosättande metod
skyddade klass findClass(String name) kastar
ClassNotFoundException
Som hittar bytekoden för en klass med en given
namn och laddar data till miljön
virtuell maskin, returnerar ett klassobjekt,
representerar den hittade klassen.
Lastarobjektet kan delegera
behörigheter att ladda klasser "förälder"
klasslastare (förälderklassladdare).
Klassladdaren "förälder" kan vara
ges som ett klasskonstruktorargument
klass lastare.

35.

skyddad ClassLoader()
Skapar ett ClassLoader-objekt, implicit
använder som "förälder"
klass loader system loader
(som kan erhållas via
anropar metoden getSystemClassLoader).
skyddad ClassLoader (ClassLoader förälder)
Skapar ett ClassLoader-objekt med hjälp av
den givna "förälder" klassladdaren.
Huvuddelen av ClassLoader-klassen
är loadClass-metoden

36.

public Сlass loadClass(String name) kastar
ClassNotFoundException
returnerar Class-objektet för klassen med det givna
namn och eventuellt laddar detta
Klass. Om klassen inte kan laddas,
ett undantag av typen kastas
ClassNot FoundException.
Klassladdningsschemat som metoden erbjuder
loadClass som standard och vanligtvis inte
override ser ut så här:
1. kolla efter metodanrop
findLoadedClass av klassen ClassLoader, inte
om den givna klassen laddades tidigare; som en del av
ClassLoader tillhandahåller objekttabell
Klass för alla klasser laddade med medel
den aktuella klasslastaren; om klassen var
laddas innan, findLoadedClass-metoden
kommer att returnera en referens till ett befintligt klassobjekt;

37.

2. om klassen inte laddades anropas den
loadClass för "förälder"-lastaren
klasser; om den aktuella starthanteraren inte är det
har en "förälder", används
systemklasslastare;
3. om klassen fortfarande inte är laddad,
metoden findClass kallas, som utför
sökning och klassladdning.
Därför är det nödvändigt att genomföra
egna versioner av följande metoder
klassladdare:

38.

skyddad synkroniserad klass
loadClass (strängnamn, boolesk upplösning)

skyddad klass findClass(String name)
kastar ClassNotFoundException
skyddad java.net.URL findResource(String name)
skyddad java.util.Enumeration
findResources(String name) kastar IOException
(Den abstrakta klassen ClassLoader representerar
endast en implementering av loadClass-metoden baserad på
på skyddade metoder - findLoadedClass och findClass).

39.

Tänk på ett exempel.
class PlayerLoader utökar ClassLoader(
public Class findClass(String name) kastar
classNotFoundException(
Prova(
byte buf = bytesForClass(namn);
return defineClass(namn, buf, 0, buf.length);
}
catch(IOException e)(
kasta nya ClassNotFoundException(e.toString());
}
}
// ... Deklarationer av bytesForClass-metoden och andra
metoder
}

40.

FindClass-metoden gör vanligtvis två saker
funktioner.
Först måste den detektera bytekoden
av den givna klassen och lagra den i en array
byte typ - denna plikt i exemplet
tilldelas bytesForСlass-metoden.
För det andra använder den den tillämpade metoden
defineClass för att göra det faktiska
laddar klassen som definieras av bytekoden.
DefineСlass-metoden ser ut

41.

skyddad slutklass defineClass(String name,
byte data, int offset, int length) kast
ClassFormatError
Returnerar Class-objektet för klassen med det angivna namnet
namn; den binära representationen av klassen skickas till
som en matrisdata.
Endast bytes används för att ladda klassen,
som ingår i elementen i datamatrisen med index
från offset till offset+längd. Om byte från den angivna
luckor uppfyller inte det format som krävs
klassdeklarationer kastas ett undantagsobjekt
av typen ClassFormatError.
Metoden ansvarar för att upprätthålla referensen till objektet
Klass för laddad klass i laddad tabell
klasser letade upp med metoden findLoadedClass.

42.

Tänk på bytesForClass-metoden.
skyddade byte bytesForClass(String name) kastar
lOException, ClassNotFoundException(
FileInputStream in = null;
Prova(


if (längd == 0) kasta ny ClassNotFoundException(namn);
byte buf = ny byte;

returbuffert;
}
till sist(
if (in!=null) in.close();
}
}

43.

Så hela koden ser ut så här:
importera java.lang.reflect.*;
importera java.io.*;
class MyClassLoader utökar ClassLoader(
offentlig klassfindClass(String name) kastar
classNotFoundException(
byte buf=ReadFromBuffer(namn);
if(name.equals("Mitt gränssnitt1"))(

) else if(buf==null) (
returnera findSystemClass(namn);
) annat (
returnera defineClass(namn,buf,0,buf.length);
}
}

44.

skyddad byte ReadFromBuffer(String name) kastar
classNotFoundException(
FileInputStream in = null;
Prova(
in = new FileInputStream(namn + ".klass");
int length = in.available(); // antal tillgängliga byte
om (längd == 0) kast
new ClassNotFoundException(namn);
byte buf = ny byte;
i read(buf); // Läs bytes
returbuffert;
}
catch(FileNotFoundException e)( return null;)
catch(IOException e)(retur null;)
till sist(
try( if (in!=null) in.close(); )
catch(IOException e)( )
}
}

45.

skyddad synkroniserad klass
loadClass (strängnamn, boolesk upplösning) kastar
classNotFoundException(
klassresultat= findClass(namn);
if (resolve) resolveClass(result);
returnera resultat;
}
}

46.

allmän klass Main1(
public static void main(String args) (
Prova(
Stringname="minklass";
ClassLoader ld=new MyClassLoader();
Klass cl=Klass.förNamn(namn, sant, ld);
Konstruktör s=cl.getConstructor(int.class);
Mitt gränssnitt 1
ob=(MyInterface1)s.newInstance(
nytt heltal(8));
System.out.println(ob.func(3,5));
)catch(Undantag e)( );
}
}

47.

offentligt gränssnitt MyInterface1(
public int func(int a,int b);
}
public class Myclass implementerar MyInterface1 (
privat int a;
public Myclass(int k) ( a=k; )
public int func(int a,int b)( return a+b; )

Vi kommer att prata om modifierare: vad är modifierare, omfattningar, modifierare för klasser, fält, metoder. Jag tror inte att det kommer att bli tråkigt.

Modifierare i Javaär nyckelord som ger en klass, klassfält eller metod vissa egenskaper.

För att indikera synligheten för en klass av dess metoder och fält, finns det fyra åtkomstmodifierare:

  • privat klassmedlemmar är endast tillgängliga inom klassen;
  • paket-privat eller standard (standard) klassmedlemmar är synliga inuti paketet;
  • skyddad klassmedlemmar är tillgängliga i paketet och i härledda klasser;
  • offentlig klassmedlemmar är tillgängliga för alla.

Om du kommer ihåg, i slutet, när vi redan hade importerat Cat-klassen, hade vi fortfarande ett kompileringsfel.

Saken är den att vi inte har registrerat några åtkomstmodifierare till våra fält och metoder, och de har en standardegenskap (klassmedlemmar är synliga inuti paketet). För att fixa kompileringsfelet för vår kod och slutligen köra den, måste vi göra vår konstruktor och våra metoder offentliga. Då kan de anropas från andra paket.

Du kanske börjar undra: vad är allt detta till för? Varför inte göra koden synlig från vilket paket eller klass som helst, men du måste begränsa åtkomsten? Dessa frågor kommer att försvinna av sig själva när det är dags att skriva komplexa och krångliga projekt. Nu, när vi skriver applikationer vars funktionalitet är begränsad till en eller två klasser, så verkar det inte vara någon mening med att begränsa någonting.

Föreställ dig att du har en klass som visar ett objekt av någon produkt. Till exempel en bil. Bilen kan ha ett pris. Du har skapat prisfältet och många andra fält, ett gäng metoder som är ansvariga för funktionaliteten. Allt verkar vara bra. Din klassbil är en del av ett stort projekt och alla är nöjda. Men låt oss säga att någon av misstag eller medvetet skapade en instans av bilklassen och satte ett negativt pris. Kan en produkt ha ett negativt pris? Det här är ett väldigt primitivt exempel och det är osannolikt att det händer i verkligheten, men jag tror att tanken är tydlig. Ibland behöver du ge åtkomst inte direkt, utan genom vissa metoder. Det kan vara så att koden är ansvarig för funktionaliteten hos en annan kod, och du inte vill att någon ska ändra och redigera en del av din. För detta finns en åtkomstbegränsning.

Åtkomstmodifieraren för konstruktörer, metoder och fält kan vara vilken som helst. En klass kan bara vara antingen offentlig eller standard, och endast en offentlig klass kan vara i en fil.

Nog om åtkomstmodifierare för nu. I artikeln "Objektorienterad programmering" kommer vi att prata om dem mer i detalj, men låt oss nu prata om andra modifierare som det förresten finns många av.

Nu är modifieraren nästa statisk. Den kan användas före en metod, ett fält eller till och med en klass när vi vill deklarera en kapslad klass. I Java kan du skriva klasser inuti andra klasser, och om modifieraren är före klassen i den statiska klassen, så kallas en sådan klass kapslad, om en annan modifierare eller standard, så kallas en sådan klass intern. Det kommer att finnas en separat artikel om kapslade och inre klasser, eftersom allt inte är så enkelt där.

Den statiska modifieraren före en metod eller ett fält indikerar att de inte tillhör en instans av denna klass. Vad betyder detta för oss? När vi har deklarerat ett klassfält eller en metod som statisk kan det anropas utan att använda en instans av klassen. Det vill säga istället för denna konstruktion: Cat cat = new Cat(); cat.method(), du kan bara skriva Cat.method(). Förutsatt att metoden deklareras som statisk. Statiska variabler är desamma för alla objekt i klassen. De har en länk.

    public class Modifiers (

    static int anotherStaticField = 5 ;

    public static void myStaticMethod() (

    someField = "Myfield" ;

    //nonStaticField = ""; kompileringsfel

    //kan inte använda icke-statiska fält

    //i statiska metoder

    public void myNonStaticMethod() (

    anotherStaticField = 4 ; //statiska fält kan användas

    //i icke-statiska metoder

    //main-metoden har också den statiska modifieraren

    new Modifiers() .myNonStaticMethod() ;

    Modificators.myStaticMethod(); //kalla statiska metoder och fält

    //via klassnamn.metod

En annan viktig anmärkning att göra om statiska modifierare är att statiska fält initieras vid klassladdningstid. Ofta i olika typer av Java-tester kan du hitta kod så här:

Fråga: vad kommer att matas ut till konsolen? Man måste komma ihåg att det statiska blocket kommer att visas först i alla fall. Därefter kommer standardblocket. Titta sedan på konsolskärmen:

Nästa modifierare vi ska titta på är slutlig.

Jag tycker att ordet final talar för sig själv. Genom att tillämpa den sista modifieraren säger du att fält inte kan ändras, metoder åsidosätts och klasser kan inte ärvas (det kommer att finnas en separat artikel om arv). Denna modifierare gäller endast klasser, metoder och variabler (även lokala variabler).

Med den sista modifieraren till metoder och klasser kommer vi att prata i OOP-artikeln.

Nästa kommer att vara modifierare som inte kommer att vara särskilt tydliga för nybörjare eller de som läser den här serien av artiklar från grunden. Och även om jag inte kan förklara allt för dig ännu (på grund av att du inte känner till det medföljande materialet), råder jag dig fortfarande att bara bekanta dig med dem. När det är dags att använda dessa modifierare kommer du redan att förstå de flesta av termerna som används nedan.

Modifierare synkroniserad indikerar att metoden endast kan användas av en tråd åt gången. Även om detta kanske inte säger dig någonting, kommer användbarheten av denna modifierare att bli uppenbar när vi utforskar multithreading.

Modifierare övergående- säger att under serialiseringen av ett objekt ska ett visst fält ignoreras. Som regel lagrar sådana fält mellanliggande värden.

Modifierare flyktig- används för multithreading. När ett fält med den flyktiga modifieraren kommer att användas och modifieras av flera trådar, säkerställer denna modifierare att fältet kommer att modifieras en i taget och det blir ingen förväxling med det.

Modifierare inföding innan metoddeklarationen anger att metoden är skriven på ett annat programmeringsspråk. Vanligtvis på C-språk.

Modifierare striktfp- Säkerställer utförande av operationer på antal av typen flytande och dubbel (flytande komma) enligt standarden IEEE 754. Eller, för att uttrycka det enklare, det garanterar att inom metoden kommer resultaten av beräkningar att vara desamma på alla plattformar.

Jag har inte pratat om modifieraren än abstrakt. Jag ska berätta kort om det, eftersom utan kunskap om grunderna i objektorienterad programmering ser jag inte poängen med att prata om det.

En klass som har den abstrakta modifieraren kan inte instansieras. Det enda syftet med det är att byggas ut. En abstrakt klass kan innehålla både abstrakta metoder och vanliga.

Vi kommer att prata mer om den abstrakta modifieraren i OOP-artikeln.

Detta avslutar artikeln om modifierare. Mycket har inte sagts om dem. Men detta beror på att vi ännu inte har begreppen OOP. I några artiklar kommer vi att utöka kunskapen om modifierare och fylla i luckorna.

Senast uppdaterad: 03.10.2019

Alla medlemmar i en klass - fält, metoder, egenskaper - de har alla åtkomstmodifierare. Åtkomstmodifierare låter dig ställa in det tillåtna omfånget för klassmedlemmar. Det vill säga, åtkomstmodifierare definierar det sammanhang i vilket en given variabel eller metod kan användas. I tidigare ämnen har vi redan stött på det när vi deklarerade klassfält som offentliga (det vill säga med den offentliga modifieraren).

C# använder följande åtkomstmodifierare:

    offentlig : offentlig, offentlig klass eller klassmedlem. En sådan klassmedlem är tillgänglig från var som helst i koden, såväl som från andra program och sammanställningar.

    privat : privat klass eller klassmedlem. Representerar raka motsatsen till den offentliga modifieraren. En sådan privat klass eller klassmedlem är endast tillgänglig från kod i samma klass eller sammanhang.

    skyddad : En sådan klassmedlem är tillgänglig var som helst i den aktuella klassen eller i härledda klasser. I det här fallet kan härledda klasser placeras i andra sammansättningar.

    intern : En klass och klassmedlemmar med en liknande modifierare är tillgängliga från var som helst i koden i samma assembly, men den är inte tillgänglig för andra program och assemblies (som är fallet med den offentliga modifieraren).

    skyddad intern : kombinerar funktionen hos två modifierare. Klasser och klassmedlemmar med denna modifierare är tillgängliga från den aktuella församlingen och från härledda klasser.

    privat skyddad : En sådan klassmedlem är tillgänglig var som helst i den aktuella klassen eller i härledda klasser som är definierade i samma sammansättning.

Vi kan uttryckligen ställa in åtkomstmodifieraren, till exempel:

Privat skyddad klass State ( intern int a; protected void Print() ( Console.WriteLine($"a = (a)"); ) )

Eller så kan vi inte specificera:

Klassstatus ( int a; void Print() ( Console.WriteLine($"a = (a)"); ) )

Om ingen åtkomstmodifierare är definierad för fält och metoder, tillämpas den privata modifieraren som standard.

Klasser och strukturer som deklareras utan modifierare har intern åtkomst som standard.

Alla klasser och strukturer som definieras direkt i namnutrymmen och som inte är kapslade i andra klasser kan bara ha offentliga eller interna modifierare.

Låt oss titta på ett exempel och skapa följande tillståndsklass:

Public class State ( // det spelar ingen roll om private int defaultVar; int defaultVar; // fältet är endast tillgängligt från den aktuella klassen private int privateVar; // tillgängligt från den aktuella klassen och härledda klasser som är definierade i samma projektskyddad privat int protectedPrivateVar; // tillgänglig från aktuell klass och härledda klasser protected int protectedVar; // tillgänglig var som helst i det aktuella projektet intern int internalVar; // tillgänglig var som helst i det aktuella projektet och från härledda klasser i andra projekt skyddade intern int protectedInternalVar; // tillgänglig var som helst i programmet, såväl som för andra program och sammansättningar public int publicVar; // som standard har den modifieraren private void defaultMethod() => Console.WriteLine($"defaultVar = (defaultVar)" ); // metoden är endast tillgänglig från den aktuella klassen private void privateMethod() => Console.WriteLine($"privateVar = (privateVar)"); // tillgänglig från den aktuella klassen och härledda klasser som är definierade i samma klausul projektskyddad privat void protectedPrivateMethod() => Console.WriteLine($"protectedPrivateVar = (protectedPrivateVar)"); // tillgänglig från den aktuella klassen och härledda klasser protected void protectedMethod()=> Console.WriteLine($"protectedVar = (protectedVar)"); // tillgänglig var som helst i det aktuella projektet intern void internalMethod() => Console.WriteLine($"internalVar = (internalVar)"); // tillgänglig var som helst i det aktuella projektet och från härledda klasser i andra projekt skyddade internt void protectedInternalMethod() => Console.WriteLine($"protectedInternalVar = (protectedInternalVar)"); // tillgänglig var som helst i programmet, såväl som för andra program och sammansättningar public void publicMethod() => Console.WriteLine($"publicVar = (publicVar)"); )

Eftersom State-klassen deklareras med den offentliga modifieraren kommer den att vara tillgänglig var som helst i programmet, såväl som från andra program och sammansättningar. Klassen State har fem fält för varje åtkomstnivå. Plus en omodifierad variabel som är privat som standard.

Det finns också sex metoder som visar värdena för klassfälten på skärmen. Observera att eftersom alla modifierare tillåter dig att använda klassmedlemmar inom denna klass, så är alla klassvariabler, inklusive privata, tillgängliga för alla dess metoder, eftersom de alla är i kontexten av klassen State.

Låt oss nu se hur vi kan använda våra klassvariabler i programmet (det vill säga i huvudmetoden för programklassen), om klasserna State och Program är i samma projekt:

Klassprogram ( static void Main(string args) ( State state1 = new State(); // vi kommer inte att kunna tilldela ett värde till defaultVar-variabeln, // eftersom den har en privat modifierare och programklassen inte ser it // Och miljön ser inte denna rad understruken som felaktig state1.defaultVar = 5; //Fel, kan inte nås // samma gäller för privateVar variabel state1.privateVar = 5; // Fel, kan inte nås // assigning värde till variabeln protectedPrivateVar kommer inte att fungera, // eftersom klassen Program inte är en klass som ärver från klassen State state1.protectedPrivateVar =5; // Fel, kan inte nås // att tilldela ett värde till variabeln protectedVar kommer också att misslyckas, // eftersom klassen Program inte är en klass som ärver från State-klassen state1.protectedVar = 5; // Fel, kan inte nås // internalVar-variabeln med den interna modifieraren är tillgänglig var som helst i det aktuella projektet // så vi kan säkert tilldela det ett värde state1.internalVar = 5; // protectedInternalVar variabel är också tillgänglig var som helst i det aktuella projektet state1.protectedInternalVar = 5; // variabel publicVar är public state1.publicVar = 5; ))

Således kunde vi bara ställa in variablerna internalVar, protectedInternalVar och publicVar, eftersom deras modifierare tillåter oss att använda dem i detta sammanhang.

Detsamma gäller för metoder:

Klassprogram ( static void Main(string args) ( State state1 = new State(); state1.defaultMethod(); //Error, kan inte nås state1.privateMethod(); // Fel, kan inte nås state1.protectedPrivateMethod() ; // Fel, kan inte nås state1.protectedMethod(); // Fel, kan inte nås state1.internalMethod(); // ok state1.protectedInternalMethod(); // ok state1.publicMethod(); // ok ) )

Här visade sig bara tre metoder vara tillgängliga för oss: internalMethod, protectedInternalMethod, publicMethod, som har modifieringarna internal, protected internal, public respektive.

Tack vare ett sådant system med åtkomstmodifierare är det möjligt att dölja vissa aspekter av klassimplementeringen från andra delar av programmet.

Trots att de offentliga och interna modifierarna är lika i sin effekt har de en stor skillnad. Klasser och klassmedlemmar med den offentliga modifieraren kommer också att vara tillgängliga för andra program, om den givna klassen placeras i en dynamisk biblioteks-dll och sedan används i dessa program.

Senaste uppdatering: 2018-04-20

Alla klassmedlemmar i Java-språket - fält och metoder - har åtkomstmodifierare. I tidigare ämnen har vi redan stött på den offentliga modifieraren. Åtkomstmodifierare låter dig ställa in det giltiga omfånget för klassmedlemmar, det vill säga det sammanhang i vilket en given variabel eller metod kan användas.

Java använder följande åtkomstmodifierare:

    offentlig : offentlig, offentlig klass eller klassmedlem. Fält och metoder som deklareras med den offentliga modifieraren är synliga för andra klasser från det aktuella paketet och från externa paket.

    privat : en privat klass eller klassmedlem, motsatsen till den offentliga modifieraren. En privat klass eller klassmedlem är endast tillgänglig från kod i samma klass.

    skyddad: en sådan klass eller klassmedlem är tillgänglig var som helst i den aktuella klassen eller paketet eller i härledda klasser, även om de finns i andra paket

    Standardmodifierare. Frånvaron av en modifierare för en fält- eller klassmetod innebär att en standardmodifierare tillämpas på den. Sådana fält eller metoder är synliga för alla klasser i det aktuella paketet.

Överväg åtkomstmodifierare med följande program som exempel:

Public class Program( public static void main(String args) (Person kate = new Person("Kate", 32, "Baker Street", "+12334567"); kate.displayName(); // ok, public kate-metod. displayAge(); // ok, metoden har standardmodifierare kate.displayPhone(); // ok, metod skyddad //kate.displayAddress(); // !Fel, metod privat System.out.println(kate.name) ; // ok, standardmodifierare System.out.println(kate.address); // ok, modifier public System.out.println(kate.age); // ok, modifierare skyddad //System.out.println( kate. phone); // ! Error, modifier private ) ) class Person( String name; protected int age; public String address; private String phone; public Person(String name, int age, String address, String phone)( this. name = namn; this.age = ålder; this.address = adress; this.phone = phone; ) public void displayName()( System.out.printf("Namn: %s \n", namn); ) void displayAge () ( System.out.printf("Ålder: %d \n", ålder); ) privat void d isplayAddress()( System.out.printf("Adress: %s \n", adress); ) protected void displayPhone()( System.out.printf("Telefon: %s \n", telefon); ))

I det här fallet finns båda klasserna i samma paket - standardpaketet, så i klassen Program kan vi använda alla metoder och variabler i klassen Person som har en standardmodifierare, offentlig och skyddad. Och fält och metoder med den privata modifieraren i programklassen kommer inte att vara tillgängliga.

Om programklassen fanns i ett annat paket skulle bara fält och metoder med den offentliga modifieraren vara tillgängliga för den.

Åtkomstmodifieraren måste föregå resten av variabeln eller metoddefinitionen.

Inkapsling

Det verkar, varför inte deklarera alla variabler och metoder med den offentliga modifieraren så att de är tillgängliga när som helst i programmet, oavsett paket eller klass? Ta till exempel åldersfältet, som representerar ålder. Om en annan klass har direkt tillgång till detta fält, finns det en chans att ett felaktigt värde skickas till den under programmet, till exempel ett negativt tal. En sådan dataändring är inte önskvärd. Eller så vill vi att vissa data ska vara tillgängliga direkt så att vi kan skriva ut dem till konsolen eller bara ta reda på dess värde. I detta avseende rekommenderas det att begränsa åtkomsten till data så mycket som möjligt för att skydda den från oönskad åtkomst utifrån (både för att få värdet och för att ändra det). Användningen av olika modifierare säkerställer att data inte skadas eller ändras på ett olämpligt sätt. Den här typen av att dölja data inom ett räckvidd kallas inkapsling.

Så, som regel, istället för att direkt använda fält, används som regel åtkomstmetoder. Till exempel:

Public class Program( public static void main(String args) ( Person kate = new Person("Kate", 30); System.out.println(kate.getAge()); // 30 kate.setAge(33); System .out.println(kate.getAge()); // 33 kate.setAge(123450); System.out.println(kate.getAge()); // 33 ) ) class Person( privat Strängnamn; privat int ålder ; public Person(String name, int age)( this.name = name; this.age = age; ) public String getName()( return this.name; ) public void setName(String name)( this.name = name; ) public int getAge()( return this.age; ) public void setAge(int age)( if(age > 0 && age)< 110) this.age = age; } }

Och sedan, istället för att arbeta direkt med namn- och åldersfälten i klassen Person, kommer vi att arbeta med metoder som ställer in och returnerar värdena för dessa fält. Metoder setName, setAge och liknande kallas även mutatorer (mutator), eftersom de ändrar fältets värden. Och metoderna getName, getAge och liknande kallas accessorer (accessor), eftersom vi med deras hjälp får värdet av fältet.

Dessutom kan vi investera ytterligare logik i dessa metoder. Till exempel, i det här fallet, när åldern ändras, görs en kontroll för att se om det nya värdet motsvarar det tillåtna intervallet.

Dela med sig