Java-modificatoren. Kenmerken van het gebruik van modifiers in Java Welke toegangsmodifier op een pakket kan worden toegepast

Modifier-klasse
De klasse Modifier codeert alle modifiers,
gebruikt in typeverklaringen, in het formulier
constanten:
SAMENVATTING, EINDE, INTERFACE, NATIVE,
PRIVÉ, BESCHERMD, OPENBAAR, STATISCH,
STRIK, SYBCHRONISEERD, TRANSIDENT,
VLUCHTIG.
Elk van de constanten wordt beantwoord door een verzoekmethode van het formulier
isMod(int modifier) ​​​​(hier is Mod een van de bovenstaande
voornamen, bijvoorbeeld isPublic),
die true retourneert als de modifier
mod is aanwezig in de typedeclaratie.

Laten we eens kijken naar een voorbeeld. Laat er zijn
veldverklaring
openbare statische finale int s=10;
vervolgens de waarde die door de methode wordt geretourneerd
getModifiers van het overeenkomstige object
klasse Veld eruit zal zien
Modifier.PUBLIC | Wijziger.STATIC |
Modifier.FINAL
De strictfp-modifier verschijnt
constant STRIK.
Querymethoden kunnen worden gebruikt
volgende vorm

Modifier.isPrivate(veld.getModifiers());
dit komt overeen met de volgende voorwaarde
(veld.getModifiers()&Modifier.PRIVATE)!=0
Klasse veld
De klasse Field implementeert methoden
waarmee u informatie kunt opvragen
veldtype, maar ook lezen en instellen
betekenis.
Laten we eens kijken naar enkele methoden van de klasse Field
1. getType() – retourneert een klasseobject
Klasse die overeenkomt met het type van het huidige veld.
Voor een veld van het type int krijgen we bijvoorbeeld
int.klasse.

2. Methoden instellen en ophalen – laat u lezen
de huidige waarde van het veld, en stel een nieuwe in.
Laten we eens kijken naar een voorbeeld:
openbare statische leegte printField(Object o,
Tekenreeksnaam) gooit
NoSuchFieldException,
IllegaleAccessException(
Veldveld = o.getClass().getField(naam);
Korte waarde = (kort) veld.get(o);
Systeem.out.println(waarde);
}
Die. get methode retourneert de waarde waarmee
verwijst naar het overeenkomstige veld of object
shell klasse.
Een voorbeeld van het gebruik van de set-methode ziet er als volgt uit:

public static void setField(Object o, Stringnaam,
korte nv) worpen
NoSuchFieldException,
IllegaleAccessException(
Veldveld = o.getClass().getField(naam) ;
veld.set(o,nieuw kort(nv));
}
Om nv op te slaan in een veld van een bepaald object
wrapper-klassen moeten worden gebruikt.
Er zijn ook methoden van het formulier
getPrimitiveType (bijvoorbeeld getInt) en
setPrimitiveType. Deze methoden kunnen zijn
gebruiken om velden in een klasse te wijzigen,
een primitief type hebben. Bijvoorbeeld,
veld.setShort(o,nv);

Methode klasse
Methodeklasse betekent: u toestaan ​​te ontvangen
volledige informatie over
verklaringen van methoden van een bepaalde klasse,
en roep indien nodig deze methoden in
context van bepaalde objecten.
Laten we eens kijken naar de methoden van de klasse Method.
1. openbare klasse getReturnType() - retourneert
het Class-object dat overeenkomt met het type
de waarde die door de huidige methode wordt geretourneerd.
Als u in plaats van de return typt
de methodedeclaratie specificeert een service
het woord leegte, zal de betreffende methode terugkeren
void.class-object.

2. openbare klasse getParameterTypes() - retourneert

parameters gespecificeerd in de advertentie
huidige methode. Objecten worden in een array ingevoerd in
in de volgorde waarin de parameters worden vermeld
methode declaratie. Als de methode dat niet heeft
parameters, wordt een lege array geretourneerd.
3. openbare klasse getExceptionTypes() - retourneert
reeks Class-objecten die overeenkomen met typen
uitzonderingen die in de zin zijn gespecificeerd
gooit declaratie van de huidige methode. Objecten
worden in de array ingevoerd in de volgorde waarin
de namen van uitzonderingstypen worden vermeld in
methode declaratie.

4. public Object aanroepen (Object onThis, Object args)
gooit IllegalAccessException,
IllegaalArgumentUitzondering,
InvocationTargetException
Roept de methode aan die door het huidige object is gedefinieerd
Methode, in de context van het onThis-object met de taak
waarden van de argumenten die door de array args worden doorgegeven.
Voor niet-statische methoden: een implementatie kiezen
uitgevoerd op basis van het daadwerkelijke type
object gedefinieerd door de parameter onThis. Voor
statische methoden onDit wordt niet geaccepteerd in
aandacht en kan nul zijn.
De lengte van de array args moet overeenkomen met het getal
parameters in de methodedeclaratie, en de objecttypen van de array-elementen moeten toewijzing mogelijk maken
overeenkomstige typen methodeparameters - in
anders wordt er een uitzondering gegenereerd
IIlegalArgumentException.

10.

Indien als onderdeel van een object gedefinieerd
onThis parameter, geen type, lid
wat is de huidige methode,
er wordt een uitzondering gegenereerd
Illegale ArgumentException.
If onThis is nul en de methode niet
statisch, er wordt een type-uitzondering gegenereerd
NullPointerException.
Als de uitvoering van de aangeroepen methode
abnormaal eindigt, wordt weggegooid
uitzondering van het type InvocationTargetException.

11.

Laten we eens kijken naar een voorbeeld. Laten we via de telefoon bellen
reflectiemethode return str.indexOf(".", 8)
dan hebben wij
poging (
Klasse strClass = str.getClass();
Methode indexM = strClass.getMethod("indexOf",
nieuwe klasse(string.class, int.class));
Objectresultaat = indexM.invoke(str, nieuw object (
".", nieuwe Integer(8)));
return ((geheel getal) resultaat).intValue();
}
catch (NoSuchMethodException e) ( …….. )
catch (aanroepTargetException e) (…….. )
vangen (illegalAccessException e) (……)

12.

Constructeursklasse
Nieuwe exemplaren (objecten) maken
typemethode kan worden gebruikt
nieuwe instantie van het Class-object,
overeenkomend met dit type.
De methode roept de constructor aan zonder argumenten,
die bij het type hoort, en retourneert een verwijzing
naar het nieuw gemaakte object van de klasse Object,
waarnaar expliciet moet worden geconverteerd
het gewenste type.
Laten we eens kijken naar een voorbeeld.

13.

statische dubbele testgegevens = ( 0.3,1.3e-2, 7.9, 3.17 );

poging (
voor(int arg = 0; arg< args.length; arg++){
Tekenreeksnaam = args;
Klasse classFor = Klasse.forName(naam);
SortDubbele sorteerder =
(SortDouble)classFor.newInstance();
SortMetrics-statistieken = sorter.sort(testData);
System.out.println(naam + ": " + statistieken);
for(int i =0; ik< testData.length; i++)
System.out.println(“ " + testData[i]); ) )
catch(Uitzondering e) ( Systeem.err.println(e); ) )

14.

newlnstance-methode als deze onjuist is
applicatie kan grote hoeveelheden weggooien
aantal verschillende uitzonderingsobjecten
typen.
InstantiationException - als klasse, object
die gecreëerd moet worden, bezit niet
een constructor zonder argumenten, of
gedefinieerd als abstract, of in
is eigenlijk een interface
of het uitvoeren van de aanmaakprocedure
object om een ​​andere reden wordt onderbroken
redenen.
IllegalAccessException - als de klasse een van beide is
constructors zonder argument zijn niet beschikbaar.

15.

SecurityException - als het beleid van kracht is
veiligheid verbiedt de creatie van nieuwe objecten
ExceptionInInitializerError – gegenereerd wanneer
initialisatie van de klasse.
De klasse Constructor definieert ook andere methoden.
openbare klasse getParameterTypes()

overeenkomend met de soorten parameters die
zijn gespecificeerd in de declaratie van de huidige constructor.
openbare klasse getExceptionTypes()
Retourneert een array met Class-objecten,
overeenkomend met de uitzonderingstypen die
gespecificeerd in de throws-clausule van de declaratie
huidige constructeur.

16.

public Object newlnstance(Objectargs)
gooit InstantiationException,
Illegale toegangUitzondering,
IllegaalArgumentUitzondering,
InvocationTargetException
Gebruikt de constructor die wordt vertegenwoordigd door de huidige
een Constructor-object om te maken en te initialiseren
een nieuw exemplaar van de klasse waarin de constructor
verklaard, waarbij de gegeven argumenten worden doorgegeven.
Retourneert een link naar het nieuw gemaakte en
geïnitialiseerd object. Lengte van de args-array
moet overeenkomen met het aantal parameters in
declaratie van de constructor en de objecttypen van de array-elementen moeten toewijzing mogelijk maken
overeenkomstige typen constructorparameters -
anders wordt er een uitzondering gegenereerd
Illegale ArgumentException.

17.

Laten we eens kijken naar een voorbeeld:
klasse Mijnklasse(
privé int a;
public Mijnklasse(int k)(a=k;)
public int func(int a,int b)(retourneert a+b;)
}
openbare klasse Hoofd(
public static void main(String args)(
poging(
Stringnaam = "Mijn klasse";
Klasse mycl=Klasse.forName(naam);
Klasse d=(int.klasse);
Constructor c=mijncl.getConstructor(d);
Mijnklasse ob=(Mijnklasse)c.newInstance(nieuw object(
nieuw geheel getal(10)));
Systeem.out.println(ob.func(3,5)); )
catch(Uitzondering e)();
}}

18.

ToegankelijkObject-klasse
De klassen Field, Constructor en Method zijn dat wel
afgeleid van de klasse AvailableObject,
die het mogelijk maakt om op te lossen of
schakel de toegangskenmerken van het controleniveau uit
talen zoals openbaar en privé.
De klasse ToegankelijkObject heeft methoden
1. public void setAccessible(booleaanse vlag)
Stelt de objecttoegangsvlag in op
volgens de argumentwaarde: waar
betekent dat het object niet langer onderworpen is aan
toegangsregels die op niveau zijn vastgesteld
taal (en zal altijd beschikbaar zijn), een false
dwingt een object om een ​​gegeven te behouden
toegangsniveau.
Als de bevoegdheid om de toegangsvlag te wijzigen
niet genoeg, er wordt een uitzondering van het type gegenereerd
Beveiligingsuitzondering

19.

2. openbare statische elektriciteit
void setAccessible(AccessibleObject-array,
Booleaanse vlag)
Hiermee kunt u de toegangsvlag instellen
objecten doorgegeven als een array.
Als u bezig bent met het verwerken van de volgende
object genereert een uitzondering van het type
SecurityException, objecten gelokaliseerd
in de eerder opgegeven array slaat u het nieuw opgegeven bestand op
toegangsniveauwaarden en alle andere
objecten blijven in dezelfde staat.
3. publieke boolean isAccessible()
Retourneert de huidige waarde van de toegangsvlag
naar het voorwerp

20.

Array-klasse
De klasse Array wordt gebruikt om een ​​array te maken
middel van reflectie.
Er worden twee vormen van de methode gebruikt om arrays te maken
nieuwInstance.
public Object newlnstance(Klasse compType, int-lengte)
Retourneert een verwijzing naar een nieuwe array van het type compType
gegeven lengte lengte.
public Object newInstance(Klasse compType, int dim)
Retourneert een verwijzing naar een nieuwe multidimensionale array van het type
compType, waarvan de afmetingen worden gespecificeerd door de waarden
elementen van de parameterarray dim.
Als de array dim leeg is of een lengte heeft groter dan
toegestaan ​​aantal afmetingen (meestal 255),

legalArgumentException.

21.

Laten we naar voorbeelden kijken.
Voorbeeld 1. Laten we een array van bytetype maken
byte ba = (byte)
Array.newlnstance(byte.class,13);
Dit is gelijkwaardig
byte ba = nieuwe byte;
Voorbeeld 2.
int dimt = (4, 4);
dubbele matrix =(dubbel)
Array.newlnstance(double.class, dimmen);
Dit is gelijkwaardig
dubbele matrix = nieuw dubbel;

22.

De klasse Array heeft methoden get en set.
Laat een array x van int-typewaarden worden gegeven; Dan
de uitdrukking xa[i] komt overeen met:
Geheel getal n=Array.get(xa, i)
U kunt als volgt een waarde aan een array-element toewijzen:
xa[ik] = 23; - dit is hetzelfde als
Array.set(xa, i, nieuw geheel getal(23));
Pakketklasse
Het aanroepen van de getPackage-methode van de klasse Class is toegestaan
haal een Package-klasseobject op met daarin
beschrijving van het pakket dat de
class (de Package-klasse zelf bevindt zich in het package
java.lang).
De methode getName() van het Package-object retourneert
De volledige naam van het huidige pakket.

23.

Proxy-klasse
Met de Proxy-klasse kunt u dynamisch creëren
klassen die een of meer implementeren
interfaces.
Stel dat er een klasse A bestaat,
het implementeren van enkele interfaces.
De Java-machine tijdens runtime kan dat wel
genereer een proxyklasse voor een gegeven
klasse A, d.w.z. het soort klasse dat
implementeert alle klasse A-interfaces, maar
vervangt het aanroepen van alle methoden hiervan
interfaces om de aanroepmethode aan te roepen,
InvocationHandler-interface, voor
waarmee u uw eigen kunt bepalen
uitvoering.

24.

Er wordt een proxyklasse gemaakt met behulp van een methodeaanroep
Proxy.getProxyClass waarvoor een ClassLoader en
een array van interfaces en retourneert een object
class java.lang.Class die is geladen met
heeft ClassLoader doorgegeven en implementeert de doorgegeven array
interfaces.
Er zijn een aantal beperkingen op de doorgegeven parameters:
1. Alle objecten in de interfaces-array moeten dat zijn
interfaces. Het kunnen geen klassen zijn of
primitieven.
2. Er kunnen geen twee identieke interfaces in de array aanwezig zijn.
voorwerpen.
3. Alle interfaces in de interface-array moeten dat zijn
geladen door de ClassLoader die aan de methode wordt doorgegeven
getProxyClass.
4. Alle niet-openbare interfaces moeten worden gedefinieerd
in hetzelfde pakket, anders gegenereerde proxyklasse
zullen ze niet allemaal kunnen uitvoeren.

25.

5. Er kunnen geen twee interfaces zijn
methode met dezelfde naam en
parameterhandtekening, maar met verschillende
retour soorten.
6. De lengte van de interface-array is beperkt
65535-interfaces. Geen Java-klasse
kan niet meer dan 65535 implementeren
interfaces.

26.

Dynamische proxyklasse-eigenschappen
1. De proxyklasse is openbaar en uitgerust
laatste modificator en is niet abstract.
2. De standaardproxyklassenaam is dat niet
gedefinieerd, maar begint bij Proxy. Alle
naamruimte beginnend met Proxy
gereserveerd voor proxyklassen
(Dit is niet nodig in recente versies van Java).
3. De proxyklasse erft van
java.lang.reflect.Proxy.
4. De proxyklasse implementeert alle interfaces,
overgedragen bij creatie, in de volgorde van overdracht.

27.

5. Als de proxyklasse een non-public
interface, dan wordt het in het pakket gegenereerd
wat dit meest niet-openbare definieert
interface. Over het algemeen een pakket waarin
de proxyklasse ongedefinieerd wordt gegenereerd.
6. De Proxy.isProxyClass-methode retourneert true for
klassen gemaakt met behulp van
Proxy.getProxyClass en voor objectklassen,
gemaakt met behulp van Proxy.newProxyInstance en
anders vals.
Deze methode wordt gebruikt door het subsysteem
Java-beveiliging en dat moet je begrijpen
klasse eenvoudigweg geërfd van
java.lang.reflect.Proxy retourneert false.

28.

De eigenschappen van de gemaakte proxyklasse-instantie zijn als volgt:
1. We brengen het proxy-klasseobject naar alle interfaces,
doorgegeven in de interfaces-array. Als IDemo een van is
overgedragen interfaces en vervolgens het proxy-exemplaar van de bewerking
IDemo retourneert altijd waar en de proxy voor de bewerking (IDemo).
zal correct eindigen.
2. Statische methode Proxy.getInvocationHandler
retourneert de oproephandler die is doorgegeven tijdens het maken
proxy-klasse-instantie. Indien hiernaar verzonden
method-object is dus geen instantie van een proxyklasse
Er wordt een IllegalArgumentException-uitzondering gegenereerd.
3. De call handler-klasse implementeert de interface
InvocationHandler, die de aanroepmethode definieert,
met de volgende handtekening:
public Object aanroepen (Objectproxy, Methodemethode,
Object args) gooit Gooibaar

29.

Laten we eens kijken naar een voorbeeld:
pakket javaapplicatie3;
interface Account (
dubbel getBalance();
void changeBalance(int som);
ongeldige procenten (dubbel per);)
klasse MyAccount implementeert Account(
privé dubbel saldo;
openbare MijnAccount() ( saldo=0.0; )
public double getBalance() ( retourneert saldo; )
public void changeBalance(int som)(
saldo+=som;)
publieke leegtepercentages(dubbel per)(
saldo+=saldo*per/100; ); )

30.

klasse MyAccountProxy implementeert
InvocationHandler(
privérekening ac;
public MijnAccountProxy(Account acc)( ac=acc; )
openbare statische account newInstance(Account da)(
return (Account)Proxy.newProxyInstance(
da.getClass().getClassLoader(),
da.getClass().getInterfaces(),
nieuwe MyAccountProxy(da));
}

31.

public Object aanroepen (objectproxy,
Methode methode, Objectargs)
gooit Gooibaar(
if(methode.getName()=="procenten")(
dubbele d=((dubbele)args).dubbelewaarde();
als(d<0) d=0;
als(d>30) d=30;
args=nieuw Dubbel(d);

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

32.

openbare klasse Hoofd(
public static void main(String args)(
MijnAccount ma=nieuw MijnAccount();
Rekening
a=(Account)MijnAccountProxy.newInstance(ma);
a.changeBalance(150);

a.procenten(20);
Systeem.out.println(a.getBalance());
a.procenten(35);
Systeem.out.println(a.getBalance());) )

33.

Lessen laden
Het runtimesysteem laadt klassen indien nodig
de behoefte eraan ontstaat.
Functionele kenmerken van laadprocedures
klassen zijn sterk afhankelijk van
implementatie van Java virtuele machines, maar in
in de meeste gevallen om klassen te vinden,
geadresseerd door de toepassing, maar niet geladen
uitvoeringssysteem, het mechanisme wordt gebruikt
bekijk het zoekpad van de klasse.
Om een ​​applicatie te maken die dit kan
klassen op andere manieren laden dan
standaard geleverd, zou u dat moeten doen
gebruik het klasseobject ClassLoader,
in staat om de bytecode van de implementatie van het gewenste te verkrijgen
class en laad deze in de runtime-omgeving
systemen.

34.

De klasse ClassLoader is een abstracte klasse.
Om uw eigen klassenlader te maken,
je moet een klasse maken die een afstammeling is van
ClassLoader en override-methode
protected Class findClass (Stringnaam) gooit
ClassNotFoundException
Welke de bytecode van een klasse met een gegeven vindt
name naam en laadt de gegevens in de omgeving
virtuele machine, die een Class-object retourneert,
die de gevonden klasse vertegenwoordigt.
Het laderobject kan delegeren
bevoegdheid om klassen naar "ouder" te laden
naar de klassenlader (bovenliggende klassenlader).
De 'ouder'-klasselader kan dat zijn
gegeven als argument aan de klassenconstructor
Klasselader.

35.

beschermde ClassLoader()
Creëert impliciet een ClassLoader-object
gebruiken als "ouder"
klasse loader systeemlader
(te verkrijgen via
roep de getSystemClassLoader-methode aan).
beschermde ClassLoader (bovenliggende ClassLoader)
Creëert een ClassLoader-object met behulp van
de opgegeven "bovenliggende" klassenlader.
Hoofdonderdeel van de ClassLoader-klasse
is de loadClass-methode

36.

public Class loadClass(Stringnaam) gooit
ClassNotFoundException
retourneert een Class-object voor de gegeven klasse
naam en laadt deze indien nodig
Klas. Als de klasse niet kan worden geladen,
er wordt een uitzondering van het type gegenereerd
ClassNotFoundException.
Klassenbelastingschema voorgesteld door de methode
loadClass is standaard en meestal niet
overschreven, ziet er als volgt uit:
1. controleer door een methode aan te roepen
findLoadedClass van ClassLoader, niet
of de opgegeven klasse al eerder is geladen; als onderdeel van
ClassLoader biedt een tabel met objecten
Klasse voor alle klassen geladen door tools
huidige klasselader; als er een klas was
eerder geladen, findLoadedClass-methode
retourneert een verwijzing naar een bestaand Class-object;

37.

2. als de klasse niet is geladen, wordt deze aangeroepen
loadClass van de "bovenliggende" lader
klassen; als de huidige bootloader dat niet is
heeft een "ouder", gebruikt
systeemklasselader;
3. als de klasse nog steeds niet is geladen,
de findClass-methode wordt aangeroepen, bezig
zoek en download klasse.
Het is dus noodzakelijk om te implementeren
aangepaste versies van de volgende methoden
Klasselader:

38.

beschermde gesynchroniseerde klasse
loadClass(tekenreeksnaam, Booleaanse oplossing)

beschermde klasse findClass(tekenreeksnaam)
genereert ClassNotFoundException
beschermde java.net.URL findResource(tekenreeksnaam)
beschermde java.util.Enumeratie
findResources(String-naam) genereert IOException
(De abstracte klasse ClassLoader vertegenwoordigt
alleen een implementatie van de loadClass-methode gebaseerd
over beschermde methoden – findLoadedClass en findClass).

39.

Laten we eens kijken naar een voorbeeld.
klasse PlayerLoader breidt ClassLoader uit (
public Class findClass(Stringnaam) gooit
ClassNotFoundException(
poging (
byte buf = bytesForClass(naam);
return definitionClass(naam, buf, 0, buf.lengte);
}
catch (IOException e) (
gooi nieuwe ClassNotFoundException(e.toString());
}
}
// ...Declaraties van de bytesForClass-methode en andere
methoden
}

40.

De findClass-methode doet doorgaans twee dingen
functies.
Eerst moet het de bytecode detecteren
gegeven klasse en sla deze op in een array
van type byte - deze plicht in het voorbeeld
toegewezen aan de bytesForСlass-methode.
Ten tweede maakt het gebruik van een applicatiemethode
definieer Сlass om het werkelijke te doen
het laden van een klasse gedefinieerd door bytecode.
De definitiemethode ziet er zo uit

41.

beschermde uiteindelijke klasse definieerklasse(tekenreeksnaam,
bytegegevens, int offset, int lengte) worpen
ClassFormatFout
Retourneert een Class-object voor de klasse met de opgegeven naam
naam; de binaire representatie van de klasse wordt doorgegeven
in de vorm van arraygegevens.
Er worden alleen bytes gebruikt om een ​​klasse te laden,
opgenomen in de elementen van de data-array met indexen
van offset naar offset+lengte. Als bytes van het opgegeven
gaten voldoen niet aan het vereiste formaat
klassebeschrijvingen, wordt een uitzonderingsobject gegenereerd
typ ClassFormatError.
De methode is verantwoordelijk voor het opslaan van een verwijzing naar het object
Klasse voor de geladen klasse in de geladen tabel
klassen opgezocht met de findLoadedClass-methode.

42.

Laten we eens kijken naar de bytesForClass-methode.
beschermde byte bytesForClass(String-naam) gooit
lOException, ClassNotFoundException(
FileInputStream in = nul;
poging (


if (lengte == 0) nieuwe ClassNotFoundException(naam);
byte buf = nieuwe byte;

terugkeer buf;
}
Eindelijk(
if (in!=null) in.close();
}
}

43.

De volledige code ziet er dus als volgt uit:
importeer java.lang.reflect.*;
java.io.* importeren;
klasse MyClassLoader breidt ClassLoader( uit
openbare klassefindClass(Stringnaam) gooit
ClassNotFoundException(
byte buf=ReadFromBuffer(naam);
if(naam.is gelijk aan("MijnInterface1"))(

) anders if(buf==null) (
return findSystemClass(naam);
) anders (
return definieerClass(naam,buf,0,buf.lengte);
}
}

44.

beschermde byte ReadFromBuffer (Stringnaam) gooit
ClassNotFoundException(
FileInputStream in = nul;
poging (
in = nieuwe FileInputStream(naam + ".class");
int lengte = in.beschikbaar(); // aantal beschikbare bytes
als (lengte == 0) worp
nieuwe ClassNotFoundException(naam);
byte buf = nieuwe byte;
in.lezen(buf); // Bytes lezen
terugkeer buf;
}
catch(FileNotFoundException e)( retourneert null;)
catch(IOException e)( retour null;)
Eindelijk(
try( if (in!=null) in.close(); )
catch(IOUitzondering e)( )
}
}

45.

beschermde gesynchroniseerde klasse
loadClass(Stringnaam,booleaanse oplossing) gooit
ClassNotFoundException(
Klasseresultaat= findClass(naam);
if (oplossen) solveClass(resultaat);
resultaat retourneren;
}
}

46.

openbare klasse Main1 (
public static void main(String args) (
poging(
Stringnaam = "Mijn klasse";
ClassLoader ld=nieuw MijnKlasseLoader();
Klasse cl=Klasse.voorNaam(naam, waar, ld);
Constructor s=cl.getConstructor(int.class);
MijnInterface1
ob=(MijnInterface1)s.newInstance(
nieuw geheel getal(8));
Systeem.out.println(ob.func(3,5));
)catch(Uitzondering e)( );
}
}

47.

openbare interface MijnInterface1(
publiek int func(int a,int b);
}
openbare klasse Myclass implementeert MyInterface1 (
privé int a;
public Mijnklasse(int k) ( a=k; )
public int func(int a,int b)( return a+b; )

Die u tijdens de initialisatie toevoegt om waarden te wijzigen. De Java-taal heeft een breed scala aan modifiers, waarvan de belangrijkste zijn:

  • toegangsmodificatoren;
  • klasse-, methode-, variabele- en threadmodifiers die worden gebruikt voor niet-toegangsdoeleinden.

Om een ​​modifier in Java te gebruiken, moet u het trefwoord ervan opnemen in de definitie van een klasse, methode of variabele. De modifier moet vóór de rest van de instructie komen, zoals weergegeven in de volgende voorbeelden:

Openbare klasse className ( // ... ) private boolean myFlag; statische laatste dubbele weken = 9,5; beschermde statische finale int BOXWIDTH = 42; public static void main(String-argumenten) ( // method body )

Toegang tot modificaties

Java biedt een aantal toegangsmodificatoren om toegangsniveaus voor klassen, variabelen, methoden en constructors te specificeren. Er zijn vier toegangen:

  • Zichtbaar in het pakket (dit is de standaard en er is geen modifier vereist).
  • Alleen zichtbaar voor de klas (privé).
  • Zichtbaar voor iedereen (openbaar).
  • Zichtbaar voor het pakket en alle subklassen (beschermd).

Standaardtoegangsmodifier - geen trefwoord

Standaard toegangsmodificator- betekent dat we niet expliciet een toegangsmodificator in Java declareren voor een klasse, veld, methode, enz.

Een variabele of methode die is gedeclareerd zonder een toegangscontrolemodifier is toegankelijk voor elke andere klasse in hetzelfde pakket. Velden in een interface zijn impliciet openbaar, statisch, definitief en methoden in een interface zijn standaard openbaar.

Voorbeeld

Variabelen en methoden kunnen in Java worden gedeclareerd zonder enige modifiers, zoals weergegeven in het volgende voorbeeld:

Stringversie = "1.5.1"; boolean processOrder() ( retourneert waar; )

Modificatie voor privétoegang

Modificator privé- methoden, variabelen en constructors die in Java als privé zijn verklaard, zijn alleen toegankelijk binnen de gedeclareerde klasse zelf.

De privétoegangsmodifier is het meest restrictieve toegangsniveau. Klasse en interfaces kunnen niet privé zijn.

Variabelen die privé zijn verklaard, zijn toegankelijk buiten de klasse als de publieke methoden die ze ontvangen in de klasse aanwezig zijn (zie voorbeeld en uitleg hieronder).

Het gebruik van de private modifier in Java is de belangrijkste manier om gegevens te verbergen.

Voorbeeld

De volgende klasse maakt gebruik van privétoegangscontrole:

Publieke klasse Logger ( private String format; public String getFormat() ( return this.format; ) public void setFormat(String format) ( this.format = format; ) )

Hier de variabele formaat klas Logger is privé, dus er is geen manier voor andere klassen om de waarde ervan rechtstreeks te verkrijgen en in te stellen.

Om deze variabele voor iedereen beschikbaar te maken, hebben we twee openbare methoden gedefinieerd: getFormat() die een waarde retourneert formaat, En setFormat(String), die zijn waarde bepaalt.

modificator voor openbare toegang

openbare modificator- klasse, methode, constructor, interface, enz. die als openbaar zijn verklaard, zijn toegankelijk vanuit elke andere klasse. Daarom zijn velden, methoden en blokken die binnen een openbare klasse zijn gedeclareerd, toegankelijk vanuit elke klasse die tot het Java-universum behoort.

Als we echter proberen toegang te krijgen tot een openbare klasse in een ander pakket, moet de openbare klasse worden geïmporteerd.

Dankzij klassenovererving worden in Java alle openbare methoden en variabelen van een klasse overgenomen door de subklassen ervan.

Voorbeeld

De volgende functie maakt gebruik van openbare toegangscontrole:

Openbare statische leegte main(String-argumenten) ( // ... )

Methode voornaamst() moet openbaar zijn. Anders kan het niet worden aangeroepen met behulp van de Java-interpreter om de klasse uit te voeren.

Toegangsmodificator beveiligd

Modificator beschermd- Variabelen, methoden en constructors die in een superklasse beschermd zijn verklaard, zijn alleen toegankelijk voor subklassen in een ander pakket of voor elke klasse in een pakket van de beschermde klasse.

De beschermde toegangsmodifier in Java kan niet worden toegepast op klassen en interfaces. Methoden en velden kunnen beschermd worden verklaard, maar methoden en velden in een interface kunnen niet beschermd worden verklaard.

Beschermde toegang geeft een subklasse de mogelijkheid om een ​​helpermethode of -variabele te gebruiken, waardoor wordt voorkomen dat een niet-gerelateerde klasse deze probeert te gebruiken.

Voorbeeld

De volgende bovenliggende klasse gebruikt het beveiligde toegangscontrole zodat de onderliggende klasse de methode overschrijft openSpeaker():

Klasse AudioPlayer ( beschermde boolean openSpeaker(Speaker sp) ( // implementatiedetails ) ) klasse StreamingAudioPlayer ( boolean openSpeaker (Speaker sp) ( // implementatiedetails ) )

Bovendien, als we een methode definiëren openSpeaker() als beschermd, dan zal het niet toegankelijk zijn vanuit een andere klasse behalve AudioPlayer. Als we het als openbaar definiëren, wordt het voor iedereen beschikbaar. Maar het is onze bedoeling om deze methode alleen aan de subklasse bloot te stellen, daarom hebben we de beschermde modifier gebruikt.

Toegangscontrole en overervingsregels

De volgende regels in Java zijn van toepassing op overgenomen methoden:

  • Methoden die openbaar zijn verklaard in de superklasse, moeten ook openbaar zijn in alle subklassen.
  • Methoden die in de superklasse beschermd zijn verklaard, moeten beschermd of openbaar zijn in subklassen; ze kunnen niet privé zijn.
  • Methoden die privé zijn verklaard, worden niet door iedereen geërfd, dus er is geen regel voor.

Klasse-, methode-, variabele- en threadmodifiers die worden gebruikt voor niet-toegangsdoeleinden

Java biedt een aantal modifiers, niet voor toegang, maar voor het implementeren van vele andere functionaliteiten:

  • modificator statisch gebruikt om klassenmethoden en variabelen te creëren;
  • modificator definitief gebruikt om de implementatie van klassen, methoden en variabelen te voltooien;
  • modificator abstract noodzakelijk voor het creëren van abstracte klassen en methoden;
  • modificatoren gesynchroniseerd En vluchtig gebruikt in Java voor threads.

Modificator statisch

Modificator statisch- gebruikt om klassenmethoden en variabelen te creëren.

statische variabelen

Het statische sleutelwoord wordt gebruikt om variabelen te creëren die onafhankelijk zullen bestaan ​​van eventuele instanties die voor de klasse zijn gemaakt. Er bestaat slechts één kopie van een statische variabele in Java, ongeacht het aantal instanties van de klasse.

Statische variabelen worden ook wel klassevariabelen genoemd. In Java kunnen lokale variabelen niet statisch worden verklaard.

statische methoden

Het statische trefwoord wordt gebruikt om methoden te maken die onafhankelijk van eventuele instances voor de klasse bestaan.

In Java gebruiken statische methoden of statische methoden geen instantievariabelen van welk klasseobject dan ook, ze zijn gedefinieerd. De statische methoden accepteren alle gegevens van de parameters en sommige van deze parameters worden berekend zonder verwijzing naar de variabelen.

Klassenvariabelen en -methoden zijn toegankelijk door de klassenaam te gebruiken, gevolgd door een punt en de naam van de variabele of methode.

Voorbeeld

De statische modifier in Java wordt gebruikt om methoden voor klassen en variabelen te maken, zoals weergegeven in het volgende voorbeeld:

Openbare klasse InstanceCounter ( private static int numInstances = 0; beschermde statische int getCount() ( return numInstances; ) private static void addInstance() ( numInstances++; ) InstanceCounter() ( InstanceCounter.addInstance(); ) public static void main(String argumenten ) ( System.out.println("Beginnend met " + InstanceCounter.getCount() + " instance"); for (int i = 0; i

Het volgende resultaat wordt verkregen:

Vanaf 0 exemplaar zijn er 500 exemplaren gemaakt

laatste modificator

laatste modificator- gebruikt om de implementatie van klassen, methoden en variabelen te voltooien.

Laatste variabelen

Een laatste variabele kan slechts één keer worden geïnitialiseerd. Een referentievariabele die als definitief is gedeclareerd, kan nooit worden toegewezen om een ​​ander object aan te duiden.

De gegevens binnen het object kunnen echter worden gewijzigd. De toestand van het object kan dus worden gewijzigd, maar niet de referentie.

Bij variabelen in Java wordt de laatste modifier vaak gebruikt bij static om een ​​klassevariabele constant te maken.

Voorbeeld

public class Test( uiteindelijke int-waarde = 10; // Hieronder staan ​​voorbeelden van constante declaraties: public static final int BOXWIDTH = 6; static final String TITLE = "Manager"; public void changeValue(){ value = 12; //будет получена ошибка } } !}

definitieve methoden

De uiteindelijke methode kan door geen enkele subklasse worden overschreven. Zoals eerder vermeld, voorkomt de laatste modifier in Java dat een methode door een subklasse wordt gewijzigd.

De belangrijkste bedoeling van het definitief maken van een methode is dat de inhoud van de methode niet naast elkaar wordt gewijzigd.

Voorbeeld

In het volgende voorbeeld wordt een methodedeclaratie getoond die de laatste modifier in een klassedeclaratie gebruikt:

Openbare klasse Test( public final void changeName())( // method body ) )

laatste les

Het belangrijkste doel in Java van het gebruik van een klasse die als definitief is gedeclareerd, is om te voorkomen dat de klasse een subklasse is. Als een klasse als definitief wordt gemarkeerd, kan geen enkele klasse een functie van de laatste klasse overnemen.

Voorbeeld

openbare eindklasse Test ( // class body )

abstracte modificator

abstracte modificator- gebruikt om abstracte klassen en methoden te creëren.

Klasse samenvatting

Een abstracte klasse kan niet instantiëren. Als een klasse abstract wordt verklaard, is uitbreiding ervan het enige doel.

Een klasse kan niet zowel abstract als definitief zijn, aangezien een laatste klasse niet kan worden uitgebreid. Als een klasse abstracte methoden bevat, moet deze abstract worden verklaard. Anders wordt er een compilatiefout gegenereerd.

De abstracte klasse kan zowel abstracte als reguliere methoden bevatten.

Voorbeeld

abstracte klasse Caravan( privé dubbele prijs; privé String-model; privé String-jaar; openbare abstracte leegte goFast(); //abstracte methode openbare abstracte leegte changeColor(); )

abstracte methode

Een abstracte methode is een methode die bij elke implementatie wordt gedeclareerd. De methodebody (implementatie) wordt geleverd door de subklasse. Abstracte methoden kunnen nooit definitief of strikt zijn.

Elke klasse die een abstracte klasse uitbreidt, moet alle abstracte methoden van de superklasse implementeren, tenzij de subklasse een abstracte klasse is.

Als een klasse in Java een of meer abstracte methoden bevat, moet de klasse abstract worden verklaard. Een abstracte klasse hoeft geen abstracte methoden te bevatten.

Een abstracte methode eindigt met een puntkomma. Voorbeeld: public abstract sample();

Voorbeeld

public abstract class SuperClass( abstract void m(); //abstract method ) class SubClass breidt SuperClass uit( // implementeert abstracte method void m())( ......... ) )

gesynchroniseerde modificator

gesynchroniseerde modificator

Het gesynchroniseerde sleutelwoord wordt gebruikt om aan te geven dat een methode slechts door één thread tegelijk toegankelijk is. In Java kan de gesynchroniseerde modifier worden toegepast met elk van de vier toegangsniveaumodifiers.

Voorbeeld

openbare gesynchroniseerde ongeldige showDetails() ( ....... )

Voorbijgaande modificator

Een instantievariabele die als tijdelijk is gemarkeerd, vertelt de Java Virtual Machine (JVM) om een ​​bepaalde variabele over te slaan bij het serialiseren van het object dat deze bevat.

Deze modifier is opgenomen in een instructie die een variabele creëert van de voorgaande klasse of het gegevenstype van de variabele.

Voorbeeld

openbare tijdelijke int-limiet = 55; // wordt niet openbaar opgeslagen int b; // wordt opgeslagen

vluchtige modificator

vluchtige modificator- gebruikt in Java voor threads.

In Java wordt de vluchtige modifier gebruikt om de JVM te laten weten dat een thread die toegang heeft tot een variabele altijd zijn eigen kopie van de variabele moet samenvoegen met de hoofdkopie in het geheugen.

Door toegang te krijgen tot een vluchtige variabele worden alle in de cache opgeslagen gekopieerde variabelen in het RAM gesynchroniseerd. Volatile kan alleen worden toegepast op instantievariabelen van het type object of private. Een vluchtige objectreferentie kan nul zijn.

Voorbeeld

public class MyRunnable implementeert Runnable( private volatile boolean active; public void run())( active = true; while (active)( // regel 1 // een code hier) ) public void stop())( active = false; / / regel 2 ) )

Doorgaans wordt run() aangeroepen op één thread (wanneer u Runnable voor het eerst gaat gebruiken in Java) en stop() wordt aangeroepen op een andere thread. Als regel 1 de in de cache opgeslagen actieve waarde gebruikt, kan de lus pas stoppen als u active op regel 2 instelt op false.

In de volgende les bespreken we de basisoperatoren die in de Java-taal worden gebruikt. In dit gedeelte krijgt u een overzicht van hoe u ze kunt gebruiken tijdens de ontwikkeling van applicaties.

5

Ik heb op StackOverflow enkele discussies over dit onderwerp gezien, maar ik zie niets dat mij heeft geholpen het volgende punt te begrijpen:

Ik heb een C++-achtergrond en ben onlangs begonnen met het leren van Java. In C++, wanneer beschermd, wordt alleen de subklasse gebruikt die toegang heeft tot het lid (analoog aan een veld in Java).

Er zijn ook "vriend"-klassen in C++ die toegang kunnen hebben tot privé/beveiligde klassencamera's die "vriendschap" geven. Dit lijkt een beetje op de veldmodifier "pakket" in Java (de standaardveldmodifier), behalve dat in C++ vriendschap toegang geeft tot alle privéleden, maar in Java is toegang vanuit klassen in hetzelfde pakket specifiek voor het klassenveld .

Wat ik niet kan bedenken, ervan uitgaande dat ik alleen toegang wil verlenen tot subklassen, is wat ik in C++ kan doen door beschermde leden te declareren in een klasse die geen vriendschappen "geeft".

Maar in Java weet ik niet hoe ik dit moet doen, omdat ik door een "beschermde" veldmodifier te gebruiken ook toegang geef tot alle klassen in het pakket. De enige manier waarop ik dit kan doen, is door een beschermd veld te declareren en de klasse in zijn eigen pakket te isoleren.

Hieruit concludeer ik dat het groeperen van klassen in één pakket moet gebeuren op basis van "vriendschap" tussen de klassen. Is dit echt de drijvende factor bij het groeperen van pakketten?

Nog iets dat ik niet begrijp: in Java, ervan uitgaande dat ik twee velden in klasse A heb: b, c. Ik wil B toegang geven tot b, maar niet tot, en ik wil C toegang geven tot c, maar niet tot b. en voor "Wereld" wil ik b, c verbergen. Hoe kan dit gedaan worden? Ik vermoed dat B, C in hetzelfde pakket zou moeten zitten als A. maar door b, c te declareren met pakket met de modifier geef ik B, C toegang tot zowel b als k. Is er een manier in Java om dit te doen?

Hoop op enige uitleg over dit onderwerp

11

Een betere vraag als deze minder nuttig voor u is, zou er een zijn die smaller en specifieker is. De algemene vraag "alles over privacy in Java en C++ en hoe ze verschillen" is meer dan een beetje te breed. Kunt u een specifiekere vraag stellen over een specifieker probleem? - Jak 04 mrt 15 04-03-2015 16:38:58

  • 4 antwoorden
  • Sorteren:

    Activiteit

2

Wanneer in C++ bescherming wordt gebruikt, heeft alleen de subklasse toegang tot het element (analoog aan een veld in Java).

Toegangsspecificaties zijn ook bedoeld voor lidfuncties/methoden, niet alleen voor lidvariabelen.

In C++ zijn er ook "vriend"-klassen die toegang kunnen hebben tot de privé/beschermde leden van de klasse, waardoor "vriendschap" ontstaat. Deze lijkt een beetje op de veldmodifier "pakket" in Java (de standaardveldmodifier), behalve dat in C++ vriendschap toegang geeft tot alle privéleden, maar in Java is toegang vanuit klassen in hetzelfde pakket specifiek voor de klasse veld.

Er zijn niet alleen vriendenklassen, maar ook functies.

Het is waar dat de toegang tot privédelen van Java vergelijkbaar is, maar het is geen volledige vervanging. Het is beter om te zeggen dat deze twee functies hebben deelverzameling de problemen die ze oplossen. Er zijn problemen die door een vriend kunnen worden opgelost, maar niet door een pakket-privé, en omgekeerd.

Wat ik niet kon bedenken, ervan uitgaande dat ik alleen toegang tot subklassen wil verlenen, is wat ik in C++ kan doen door gebruikers beschermd te verklaren in een klasse die geen vriendschap "geeft".

Maar op Java weet ik niet hoe ik dit moet doen,

Antwoord: Dat kan niet.

omdat ik door een "beschermde" veldmodificator te gebruiken ook toegang geef tot alle klassen in het pakket.

De enige manier die ik vind is door een beschermd veld aan te geven en de klasse in zijn pakket te isoleren.

Technisch gezien wel. Maar dit schept andere problemen. Uw klas heeft geen toegang meer tot de privépakketonderdelen van het vorige pakket. Laten we zeggen dat uw BaseClass zich in com.example.one bevond. Je verplaatst het naar com.example.two. Nu heeft het geen toegang meer tot andere privélespakketten com.example.one.

Is dit echt de drijvende factor bij het groeperen van pakketten?

Ja, Java is op deze manier ontworpen. Je kunt het proberen strijd tegen de taalregels, maar dat is in elke programmeertaal een verloren strijd.

Een ander ding dat ik niet begrijp, is in Java, ervan uitgaande dat ik twee velden in klasse A heb: b, c. Ik wil B toegang geven tot b, maar niet tot, en ik wil C toegang geven tot c, maar niet tot b. en in "Wereld" wil ik dat b, c zich verstopt. Hoe kan dit gedaan worden?

Dit kan niet op een schone manier worden gedaan (met schoon bedoel ik: zonder enige hacks waarbij je de call-stack tijdens runtime moet controleren en uitzonderingen moet genereren).

Als u zich zorgen maakt over dit scenario omdat u een openbare API ontwikkelt, is een low-tech oplossing die meestal prima werkt het maken van een of meer *.internal-pakketten en documenteert u duidelijk het feit dat deze niet in clientcode mogen worden gebruikt.

1

Dat zijn nogal wat vragen bij elkaar...

Maar in Java weet ik niet hoe ik dit kan doen, omdat ik door het gebruik van een "beschermde" veldmodifier ook toegang geef tot alle klassen in het pakket.

Er is inderdaad geen manier om alleen toegang te verlenen tot subklassen, maar niet tot klassen in hetzelfde pakket. Dit was een ontwerpbeslissing die eeuwen geleden werd genomen...

De enige manier waarop ik dit kan doen, is door een beschermd veld aan te geven en dit in uw pakket te isoleren.

Dit is technisch correct, hoewel het weinig nut zal hebben. Klassenverpakking is bedoeld om gerelateerde klassen te groeperen, waarbij "gerelateerd" betekent "klassen die een specifieke relatie uitvoeren", dat wil zeggen dat ze tot dezelfde use case behoren, tot hetzelfde architecturale niveau behoren, zich in dezelfde essentie bevinden, enz.

Hieruit concludeer ik dat het groeperen van klassen in één pakket moet gebeuren op basis van "vriendschap" tussen de klassen. Is dit echt de drijvende factor bij het groeperen van pakketten?

Ik geloof dat ik dit al in de vorige paragraaf heb beantwoord: verpakkingen zijn ontworpen om gerelateerde klassen te groeperen volgens een aantal specifieke criteria.

Voor uw A-, B- en C-klassen, bijvoorbeeld met attributen:

Ik denk dat B en C beide in hetzelfde pakket moeten zitten, A. a die b declareert, met de verpakkingsmodificator laat ik B, C toegang krijgen tot zowel b als k.

Het antwoord is nee, er is geen eenvoudige en duidelijke manier om dit te doen. Je zou dit kunnen bereiken met wat hacks of meer geavanceerde technieken, maar nogmaals, dit was lang geleden onderdeel van de beslissingen die de taalontwikkelaars namen...

0

Kort antwoord: er is geen manier om dit te doen.

Als u zich zorgen maakt over inbraak door clients die klasse in het pakket injecteren om ongeoorloofde toegang te verkrijgen, kunt u de gevoelige code in een afzonderlijk pakket verplaatsen en het pakket verzegelen in een pot waar u het aan aflevert: http://docs.oracle. com/javase/tutorial/deployment/jar/sealman.html

1

Impliciet wordt aangenomen dat alle klassen in een pakket elkaar "kennen" (omdat ze door dezelfde persoon/bedrijf/organisatie zijn geschreven). Ze hebben dus óf geen toegang tot beveiligde velden, óf als ze dat wel doen, weten ze hoe ze dat op de juiste manier moeten doen.

Er wordt verondersteld dat de klassen in hetzelfde pakket meer aan elkaar gerelateerd zijn dan de ouder aan de afgeleide klasse, omdat de afgeleide klasse in werkelijkheid door iemand anders kan zijn geschreven. Ze besloten daarom dat de particuliere bescherming beperkter was dan ze werd beschermd.

Ik denk dus dat je je geen zorgen hoeft te maken over de manier waarop klassen in hetzelfde pakket toegang krijgen tot elkaars velden. Over het algemeen gebruik ik deze functie niet, behalve wanneer ik iterators schrijf.

Als je twee velden hebt, kun je er binnenklassen van maken, zodat ze toegang hebben tot de privévelden (nogmaals, logica: als een klasse zich in een andere klasse bevindt, kent deze de semantiek van die klasse) en kan die toegang bieden tot hun eigen velden. afgeleide klassen via veilige methoden.

Natuurlijk zou je een complex tokenuitwisselingsprotocol kunnen bedenken om dit veld alleen toegankelijk te maken voor B/C-instanties, maar dat zou een prachtige overhead zijn, en het andere object zou nog steeds reflectie kunnen gebruiken om toegang te krijgen tot alle privéleden als je dat niet doet. Je kunt het niet uitschakelen via beveiligingsbeleid, wat meestal niet het geval is, maar nogmaals, het beveiligingsbeleid wordt uiteindelijk bepaald door de JVM-eigenaar.

Dus uiteindelijk is de beste manier om te doen wat je zegt in Java, ze in hetzelfde pakket te plaatsen, of B en C te schrijven als binnenklassen van A, zodat ze rechtstreeks toegang hebben tot privéleden van A en ze blootstellen aan de afgeleide klassen. .

Publieke klasse A ( publieke statische abstracte klasse B ( beschermd Wat dan ook getWhatever(A a) ( return a.b; ) beschermde void setWhatever(A a, Welke waarde dan ook) ( a.b = waarde; ) ) publieke statische abstracte klasse C ( beschermd Wat dan ook getWhatever (A a) ( return a.c; ) protected void setWhatever(A a, Welke waarde dan ook) ( ​a.c = waarde; ) ) private Wat dan ook privé Wat dan ook c)

nogmaals, je gaat er altijd van uit dat klassen in hetzelfde pakket nooit iets verkeerd zullen doen.

Laatste update: 20/04/2018

Alle klasseleden in Java - velden en methoden - hebben toegangsmodificatoren. In eerdere onderwerpen zijn we de openbare modifier al tegengekomen. Met toegangsmodifiers kunt u het toegestane bereik voor klasseleden instellen, dat wil zeggen de context waarin een bepaalde variabele of methode kan worden gebruikt.

Java gebruikt de volgende toegangsmodifiers:

    openbaar : een openbare, openbare klasse of lid van een klasse. Velden en methoden die met de public modifier zijn gedeclareerd, zijn zichtbaar voor andere klassen uit het huidige pakket en voor externe pakketten.

    private : Een privéklasse of klaslid, het tegenovergestelde van de publieke modifier. Een privéklas of klaslid is alleen toegankelijk via code in dezelfde klas.

    beschermd: zo'n klasse of klasselid is overal toegankelijk in de huidige klasse of het huidige pakket of in afgeleide klassen, zelfs als ze zich in andere pakketten bevinden

    Standaardmodificator. De afwezigheid van een modifier voor een klassenveld of -methode impliceert dat de standaardmodifier erop wordt toegepast. Dergelijke velden of methoden zijn zichtbaar voor alle klassen in het huidige pakket.

Laten we naar toegangsmodificatoren kijken met het volgende programma als voorbeeld:

Public class Program( public static void main(String args) ( Person kate = new Person("Kate", 32, "Baker Street", "+12334567"); kate.displayName(); // normal, method public kate. displayAge(); // ok, de methode heeft een standaard modifier kate.displayPhone(); // ok, methode beveiligd //kate.displayAddress(); // Fout, methode private System.out.println(kate.name) ; // ok, standaard modificatie System.out.println(kate.address); // ok, modificatie public System.out.println(kate.age); // ok, modificatie beschermd //System.out.println( kate .phone); // ! Error, modifier private ) ) class Person( Stringnaam; beschermde int-leeftijd; openbaar String-adres; privé String-telefoon; public Person(String-naam, int-leeftijd, String-adres, String-telefoon)( this. name); = naam; this.age = leeftijd; this.address = adres; this.phone = telefoon ()( System.out.printf("Leeftijd: %d \n", leeftijd); ) private void displayAddress()) ( System.out.printf("Adres: %s \n", adres);

In dit geval bevinden beide klassen zich in één pakket: het standaardpakket, dus in de klasse Program kunnen we alle methoden en variabelen van de klasse Person gebruiken, die de standaardmodifier public en protected hebben. En velden en methoden met de private modifier in de Program-klasse zullen niet beschikbaar zijn.

Als de klasse Program zich in een ander pakket zou bevinden, zouden alleen velden en methoden met de publieke modifier beschikbaar zijn.

De toegangsmodificator moet voorafgaan aan de rest van de variabele of methodedefinitie.

Inkapseling

Het lijkt erop dat, waarom zouden we niet alle variabelen en methoden declareren met de publieke modifier, zodat ze overal in het programma beschikbaar zijn, ongeacht het pakket of de klasse? Neem bijvoorbeeld het leeftijdsveld, dat de leeftijd vertegenwoordigt. Als een andere klasse directe toegang heeft tot dit veld, bestaat de mogelijkheid dat er tijdens de werking van het programma een onjuiste waarde wordt doorgegeven, bijvoorbeeld een negatief getal. Een dergelijke gegevenswijziging is niet aan te raden. Of we willen dat sommige gegevens direct toegankelijk zijn, zodat we deze op de console kunnen weergeven of eenvoudigweg de waarde ervan kunnen achterhalen. In dit verband wordt aanbevolen om de toegang tot gegevens zoveel mogelijk te beperken om deze te beschermen tegen ongewenste toegang van buitenaf (zowel om de waarde te verkrijgen als om deze te wijzigen). Het gebruik van verschillende modifiers zorgt ervoor dat de gegevens niet beschadigd raken of op ongepaste wijze worden gewijzigd. Het op deze manier verbergen van gegevens binnen een bereik wordt inkapseling genoemd.

Dus in plaats van velden rechtstreeks te gebruiken, worden in de regel meestal toegangsmethoden gebruikt. Bijvoorbeeld:

Public class Program( public static void main(String args) ( Person kate = new Person("Kate", 30); System.out.println(kate.getAge()); // 30 kate.setAge(33); Systeem .out.println(kate.getAge()); // 33 kate.setAge(123450); System.out.println(kate.getAge() // 33 ) class Person( private String-naam; private int age ; public Person(String naam, int age)( this.name = naam; this.age = leeftijd; ) public String getName() ( return this.name; ) public void setName(String name)( this.name = naam; ) public int getAge() ( return this.age; ) public void setAge(int age)( if(age > 0 && age< 110) this.age = age; } }

En dan gaan we, in plaats van rechtstreeks te werken met de naam- en leeftijdsvelden in de klasse Person, werken met methoden die de waarden van deze velden instellen en retourneren. Methoden setName, setAge en dergelijke worden ook wel mutators genoemd, omdat ze de waarden van een veld veranderen. En de methoden getName, getAge en dergelijke worden accessors genoemd, omdat we met hun hulp de waarde van het veld verkrijgen.

Bovendien kunnen we extra logica in deze methoden stoppen. In dit geval wordt er bijvoorbeeld, wanneer de leeftijd verandert, gecontroleerd of de nieuwe waarde binnen het acceptabele bereik past.

De Java-taal biedt veel modifiers, onderverdeeld in de volgende categorieën:

  • toegangsmodificator
  • Niet-toegangsmodifier

Een modifier wordt gebruikt om een ​​klasse, methode of variabele te definiëren, meestal op de voorgrond van een instructie. Via het volgende voorbeeld ter illustratie:

Openbare klasse className ( // ... ) private boolean myFlag; statische laatste dubbele weken = 9,5; beschermde statische finale int BOXWIDTH = 42; public static void main(String-argumenten) ( // 方法体 )

Toegangscontrolemodificator

Java kunt u toegangscontrolesymbolen gebruiken om de toegang tot klassen, variabelen, methoden en constructors te beschermen. Java ondersteunt vier verschillende machtigingen.

Standaard, ook wel standaard genoemd standaard, zichtbaar in hetzelfde pakket, gebruik geen enkele modifier.

Privé tot gespecificeerd privé een modifier die zichtbaar is binnen dezelfde klasse.

Ja, om aan te geven algemeen een modifier die zichtbaar is voor alle klassen.

Beschermd, op beschermd De modifier specificeert dat alle klassen en subklassen binnen hetzelfde pakket zichtbaar zijn.

De standaardtoegangsmodifier is om geen trefwoorden te gebruiken

Gebruik variabelen en methoden die zijn gedeclareerd in de standaardtoegangsmodifier voor een klasse binnen hetzelfde zichtbare pakket. Een interface waarbij de variabelen impliciet worden gedeclareerd als een openbare statische finale, en een interface waarbij de standaardtoegang voor het publiek is.

In het volgende voorbeeld kunnen variabelen en methoden geen enkele modifier gebruiken.

Stringversie = "1.5.1"; boolean processOrder() ( retourneert waar; )

Modifier voor privétoegang: privé

De private access modifier is het meest restrictieve toegangsniveau; het wordt gedeclareerd als private methoden en variabelen, en behoort tot de constructorklasse waar alleen toegang toe is, en klassen en interfaces kunnen niet privé worden verklaard.

Variabelen die zijn gedeclareerd als een privétoegangstype zijn alleen toegankelijk buiten de klasse via de public getter-methode van de klasse.

De Private Access-modifier wordt voornamelijk gebruikt om implementatiedetails en gegevens per klasse te beschermen.

De volgende klassen gebruiken de privétoegangsmodifier:

Publieke klasse Logger ( private String format; public String getFormat() ( return this.format; ) public void setFormat(String format) ( this.format = format; ) )

Het variabeleformaat van de Logger-klasse is bijvoorbeeld een privévariabele, dus andere klassen kunnen de waarde van de variabele niet rechtstreeks ophalen en instellen. Om met een andere klassevariabele te kunnen werken, definieert het twee openbare methoden: GetFormat () (retourwaardeformaat) en SetFormat (String) (formaatinstelling)

Modifier voor open toegang - openbaar

Het wordt gedeclareerd als openbare klassen, methoden, constructors en interfaces die elk ander toegangstype kunnen zijn.

Als er meerdere gezamenlijke bezoeken van openbare klassen in verschillende pakketten zijn, moet u het corresponderende pakket van de openbare klasse die zich permanent bevindt importeren. Sinds klassenovererving kunnen alle openbare methoden en variabelen van een klasse worden overgenomen door zijn subklassen.

De volgende functies maken gebruik van openbare toegangscontrole:

Openbare statische leegte main(String-argumenten) ( // ... )

De belangrijkste Java-programma()-methode moet worden ingesteld op public, anders kan de Java-interpreter de klasse niet uitvoeren.

Beschermde toegangsmodifiers beschermd

Methoden en constructors in hetzelfde pakket, gedeclareerd als beschermde variabelen, kunnen elk ander toegangstype hebben en zijn toegankelijk in pakketten van verschillende subklassen.

Beveiligde toegangsmodificatieklassen en interfaces kunnen niet worden gewijzigd, en lidvariabelen kunnen als beschermd worden gedeclareerd, maar interfacevariabelen en lidmethoden kunnen niet als beschermd worden verklaard.

modifier Subklassen hebben toegang tot gedeclareerde beschermde methoden en variabelen, zodat we niet-gerelateerde klassen kunnen beschermen met behulp van deze methoden en variabelen.

De volgende bovenliggende klasse gebruikt een beschermde toegangsmodifier; subklassen overschrijven de openSpeaker() -methode van de bovenliggende klasse.

Class AudioPlayer ( protected boolean openSpeaker(Speaker sp) ( // 实现细节 ) ) class StreamingAudioPlayer ( boolean openSpeaker(Speaker sp) ( // 实现细节 ) )

Als de methode openSpeaker() privé wordt verklaard, is de methode, naast de klasse AudioPlayer, niet toegankelijk. Als openSpeaker() openbaar wordt verklaard, hebben alle klassen toegang tot de methode. Als we het proces zichtbaar willen maken voor subklassen van de klasse, wordt de methode als beschermd verklaard.

Toegangscontrole en overerving

Houd er rekening mee dat de volgende methoden de regels overnemen:

    De bovenliggende klasse wordt gedeclareerd als openbare methoden, terwijl de subklasse ook openbaar moet zijn.

    De Parent-klasse wordt gedeclareerd als een beschermde methode in een subklasse, ofwel als beschermd ofwel publiekelijk gedeclareerd. U kunt niet privé worden verklaard.

    Een bovenliggende klasse die als privémethode is gedeclareerd, kan niet worden overgenomen.

Niet-toegangsmodifier

Om een ​​aantal andere functies te bereiken, biedt Java ook een aantal niet-toegangsmodificatoren.

De statische modifier wordt gebruikt om klassemethoden en klassevariabelen te maken.

De laatste modifier die wordt gebruikt om klassen, methoden en variabelen te versieren, de laatste gewijzigde klasse kan niet worden geërfd, de gewijzigde klassenmethode kan niet worden geërfd, overschreven, gewijzigde constante variabelen kunnen niet worden gewijzigd.

De abstracte modifier wordt gebruikt om abstracte klassen en abstracte methoden te maken.

Synchrone en vluchtige modifiers, voornamelijk voor het programmeren van threads.

Statische modificator

    Statische variabelen:

    Het static trefwoord wordt gebruikt om statische variabelen te declareren die onafhankelijk zijn van een object. Ongeacht hoeveel objecten een instantie van een klasse heeft, het is slechts één kopie van de statische variabele. Statische variabelen worden ook wel klassevariabelen genoemd. Lokale variabelen kunnen niet als statische variabelen worden gedeclareerd.

    Statische methoden:

    Het statische trefwoord wordt gebruikt om een ​​object onafhankelijk van een statische methode te declareren. Statische methoden kunnen geen niet-statische variabelenklasse gebruiken. Statische methode om gegevens uit een lijst met parameters te halen en vervolgens de gegevens te berekenen.

Toegang tot klassenvariabelen en methoden kunnen rechtstreeks worden gebruikt door toegang te krijgen tot classname.variablename en classname.methodname.

In het volgende voorbeeld wordt een statische modifier gebruikt om klassemethoden en klassevariabelen te maken.

Openbare klasse InstanceCounter ( private static int numInstances = 0; beschermde statische int getCount() ( return numInstances; ) private static void addInstance() ( numInstances++; ) InstanceCounter() ( InstanceCounter.addInstance(); ) public static void main(String argumenten ) ( System.out.println("Beginnend met " + InstanceCounter.getCount() + " instances"); for (int i = 0; i< 500; ++i){ new InstanceCounter(); } System.out.println("Created " + InstanceCounter.getCount() + " instances"); } }

Voorbeelden van de bovenstaande resultaten van de bewerkingsbewerking zijn als volgt:

Gestart met 0 exemplaren. 500 exemplaren gemaakt

Laatste classificatie

Laatste variabelen:

Eindvariabelen kunnen expliciet worden geïnitialiseerd en worden slechts één keer geïnitialiseerd. Een map wordt gedeclareerd omdat eindobjecten niet naar een ander object kunnen verwijzen. Maar het einddoel is waar de gegevens kunnen worden gewijzigd. Dit is een laatste verwijzing naar een object dat niet kan worden gewijzigd, maar waarvan de waarde wel kan worden gewijzigd.

De laatste modifier wordt meestal samen gebruikt om een ​​statische modifier-klasseconstante te creëren.

Publieke klasse Test( uiteindelijke int-waarde = 10; // publieke statische finale int BOXWIDTH = 6; statische finale String TITLE = "Manager"; public void changeValue(){ value = 12; //将输出一个错误 } } !}

Laatste methode

Methoden van een laatste klasse worden overgenomen door subklassen, maar subklassen kunnen deze niet wijzigen.

Het belangrijkste doel van een methode is om te voorkomen dat de definitieve verklaring van die methode wordt gewijzigd.

Zoals hieronder zal worden getoond, wordt gebruik gemaakt van de laatste methoden van declaratiemodificatoren.

Publieke klasse Test( public final void changeName())( // 方法体 ) )

Laatste categorie

Eindklassen kunnen niet worden geërfd; geen enkele klasse kan de kenmerken van een eindklasse erven.

Openbare eindklasse Test ( // 类体 )

Abstracte modificator

Abstracte klasse:

Een abstracte klasse kan niet worden gebruikt om een ​​object te instantiëren; het enige doel van de instructie is het creëren van een abstracte klasse voor toekomstige uitbreiding van die klasse.

Een klasse kan niet abstract en definitief worden gewijzigd. Als een klasse abstracte methoden bevat, moet de klasse als een abstracte klasse worden gedeclareerd, anders treedt er een compileerfout op.

Een abstracte klasse kan abstracte methoden en niet-abstracte methoden bevatten.

Abstract class Caravan( private double price; private String model; private String year; public abstract void goFast(); //抽象方法 public abstract void changeColor(); )

Abstracte methode

Geen enkele methode is een abstracte methode-implementatie; een concrete methode-implementatie wordt geleverd door subklassen. Abstracte methoden kunnen niet als definitief en strikt worden beschouwd.

Elke subklasse die een abstracte klasse erft, moet alle abstracte methoden van de bovenliggende klasse implementeren, tenzij de subklasse een abstracte klasse is.

Als een klasse meerdere abstracte methoden bevat, moet de klasse als abstracte klasse worden gedeclareerd. Een abstracte klasse kan geen abstracte methoden bevatten.

Een declaratie van een abstracte methode eindigt met een puntkomma, bijvoorbeeld: public abstract patroon();

Openbare abstracte klasse SuperClass( abstract void m(); //抽象方法 ) klasse SubClass breidt SuperClass( //实现抽象方法 void m())( ......... ) ) uit

Synchrone modificator

Methode Synchronisch sleutelwoord om tegelijkertijd aan te geven dat slechts één thread toegang heeft. De synchrone modifier kan worden toegepast op vier toegangsmodifiers.

Openbare gesynchroniseerde ongeldige showDetails() ( ....... )

Overgangsmodificator

Het geserialiseerde object bevat tijdelijke variabelen die zijn aangepast door de Java Virtual Machine (JVM)-instantie om die specifieke variabele over te slaan.

De modifier is opgenomen in de definitie van instructievariabelen om gegevenstypeklassen en variabelen voor te verwerken.

Openbare tijdelijke int-limiet = 55; // zal niet openbaar blijven int b; // zal blijven bestaan

Vluchtige modificatoren

Een vluchtige gewijzigde lidvariabele dwingt threads om de waarde van de lidvariabele uit het gedeelde geheugen opnieuw te lezen telkens wanneer deze wordt geopend. Bovendien wordt de thread, wanneer lidvariabelen veranderen, gedwongen de waarde te wijzigen die naar het gedeelde geheugen wordt teruggeschreven. Dus op elk gegeven moment zien twee verschillende onderwerpen altijd dezelfde waarde voor een lidvariabele.

Publieke klasse MyRunnable implementeert Runnable ( private volatile boolean active; public void run() ( active = true; while (active) // 第一行 ( // 代码 ) ) public void stop() ( active = false; // 第二行 ) )

Onder normale omstandigheden roept een thread de methode Run() aan (in Runnable van een geopende thread) in een andere thread die de methode Stop() aanroept. Als de actieve waarde in eerste regel buffer wordt gebruikt tweede rij wanneer de actieve lus onwaar is, stopt deze niet.

In de bovenstaande code gebruiken we echter een gemodificeerde vluchtige actieve stof, dus de lus stopt.