(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)
目录
一、Java修饰符
Java语言提供了很多修饰符,主要分为以下两类:
访问修饰符
非访问修饰符
修饰符用来定义类、方法或者变量,通常放在语句的最前端。我们通过下面的例子来说明:
public class className { // ... } private boolean myFlag; static final double weeks = 9.5; protected static final int BOXWIDTH = 42; public static void main(String[] arguments) { // 方法体 }
访问控制修饰符
Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java支持4种不同的访问权限。
默认的,也称为default,在同一包内可见,不使用任何修饰符。
私有的,以private修饰符指定,在同一类内可见。
共有的,以public修饰符指定,对所有类可见。
受保护的,以protected修饰符指定,对同一包内的类和所有子类可见。
默认访问修饰符-不使用任何关键字
使用默认访问修饰符声明的变量和方法,对同一个包内的类是可见的。接口里的变量都隐式声明为public static final,而接口里的方法默认情况下访问权限为public。
实例:
如下例所示,变量和方法的声明可以不使用任何修饰符。
String version = "1.5.1"; boolean processOrder() { return true; }
私有访问修饰符-private
私有访问修饰符是最严格的访问级别,所以被声明为private的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为private。
声明为私有访问类型的变量只能通过类中公共的getter方法被外部类访问。
Private访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据。
下面的类使用了私有访问修饰符:
public class Logger { private String format; public String getFormat() { return this.format; } public void setFormat(String format) { this.format = format; } }实例中,Logger类中的format变量为私有变量,所以其他类不能直接得到和设置该变量的值。为了使其他类能够操作该变量,定义了两个public方法:getFormat() (返回format的值)和setFormat(String)(设置format的值)
公有访问修饰符-public
被声明为public的类、方法、构造方法和接口能够被任何其他类访问。
如果几个相互访问的public类分布在不同的包中,则需要导入相应public类所在的包。由于类的继承性,类所有的公有方法和变量都能被其子类继承。
以下函数使用了公有访问控制:
public static void main(String[] arguments) { // ... }Java程序的main() 方法必须设置成公有的,否则,Java解释器将不能运行该类。
受保护的访问修饰符-protected
被声明为protected的变量、方法和构造器能被同一个包中的任何其他类访问,也能够被不同包中的子类访问。
Protected访问修饰符不能修饰类和接口,方法和成员变量能够声明为protected,但是接口的成员变量和成员方法不能声明为protected。
子类能访问Protected修饰符声明的方法和变量,这样就能保护不相关的类使用这些方法和变量。
下面的父类使用了protected访问修饰符,子类重载了父类的openSpeaker()方法。
class AudioPlayer { protected boolean openSpeaker(Speaker sp) { // 实现细节 } } class StreamingAudioPlayer { boolean openSpeaker(Speaker sp) { // 实现细节 } }如果把openSpeaker()方法声明为private,那么除了AudioPlayer之外的类将不能访问该方法。如果把openSpeaker()声明为public,那么所有的类都能够访问该方法。如果我们只想让该方法对其所在类的子类可见,则将该方法声明为protected
访问控制和继承
请注意以下方法继承的规则:
父类中声明为public的方法在子类中也必须为public。
父类中声明为protected的方法在子类中要么声明为protected,要么声明为public。不能声明为private。
父类中声明为private的方法,不能够被继承。
非访问修饰符
为了实现一些其他的功能,Java也提供了许多非访问修饰符。
static修饰符,用来创建类方法和类变量。
final修饰符,用来修饰类、方法和变量,final修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
abstract修饰符,用来创建抽象类和抽象方法。
synchronized和volatile修饰符,主要用于线程的编程。
static修饰符
静态变量:
static关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。静态变量也被称为类变量。局部变量不能被声明为static变量。
静态方法:
static关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。
对类变量和方法的访问可以直接使用classname.variablename和classname.methodname的方式访问。
如下例所示,static修饰符用来创建类方法和类变量。
public class InstanceCounter { private static int numInstances = 0; protected static int getCount() { return numInstances; } private static void addInstance() { numInstances++; } InstanceCounter() { InstanceCounter.addInstance(); } public static void main(String[] arguments) { System.out.println("Starting with " + InstanceCounter.getCount() + " instances"); for (int i = 0; i < 500; ++i){ new InstanceCounter(); } System.out.println("Created " + InstanceCounter.getCount() + " instances"); } }以上实例运行编辑结果如下
Started with 0 instances Created 500 instances
二、静态方法
类可以有两种类型的方法:实例方法和类方法。实例方法和类方法也分别称为非静态方法和静态方法。
实例方法用于实现类的实例的行为。实例方法只能在类的实例的上下文中调用。
类方法用于实现类本身的行为。类方法总是在类的上下文中执行。
静态修饰符用于定义类方法。方法声明中缺少静态修饰符,使得该方法成为一个实例方法。
以下是声明一些静态和非静态方法的示例:
// A static or class method static void aClassMethod() { } // A non-static or instance method void anInstanceMethod() { }
注意
当调用类的静态方法时,该类的实例可能不存在。因此,不允许从静态方法内部引用实例变量。
类定义一加载到内存中,类变量就存在。类定义在创建类的第一个实例之前加载到内存中。
类方法或静态方法只能引用类的变量或类的静态变量。实例方法或非静态方法可以引用类变量以及类的实例变量。
以下代码演示了在方法中可访问的类字段的类型。
public class Main { static int m = 100; // A static variable int n = 200; // An instance variable // Declare a static method static void printM() { /* * We can refer to only static variable m in this method because you are * inside a static method */ System.out.println("printM() - m = " + m); } // Declare an instance method void printMN() { /* We can refer to both static and instance variables m and n in this method */ System.out.println("printMN() - m = " + m); System.out.println("printMN() - n = " + n); } }
调用方法
在方法的主体中执行代码称为调用(或调用)方法。
实例方法和类方法以不同方式调用。
使用点表示法在类的实例上调用实例方法。
<instance reference>.<instance method name>(<actual parameters>)在调用该类的实例方法之前,我们必须引用一个类的实例。
以下代码显示如何调用Main类的printMN()实例方法:
// Create an instance of Main class and // store its reference in mt reference variable Main mt = new Main(); // Invoke the printMN() instance method using the mt reference variable mt.printMN();要调用类方法,请使用带有名称的点表示法。
下面的代码调用Main类的printM()类方法:
// Invoke the printM() class method Main.printM();属于一个类的属性也属于该类的所有实例。我们还可以使用该类的实例的引用来调用类方法。
Main mt = new Main(); mt.printM(); // Call the class method using an instance mt使用类名调用类方法比使用实例引用更直观。
三、静态代码块
实例初始化块
实例初始化块用于初始化类的对象。
一个实例初始化程序只是一个类的代码块,但在任何方法或构造函数之外。
实例初始值设定程序没有名称。它的代码只是放置在一个开放大括号和闭包。
下面的代码展示了如何为Test类声明一个实例初始化器。
注意,实例初始化程序在实例上下文中执行,并且关键字this在实例初始化程序中可用。
class Test { private int num; // An instance initializer { this.num = 101; /* Other code for the instance initializer*/ } /* Other code for Test class*/ }
多重实例初始化
我们可以有一个类的多个实例初始化器。对于我们创建的每个对象,它们都以文本顺序自动执行。
所有实例初始值的代码在任何构造函数之前执行。
下面的代码演示了构造函数和实例初始化函数的执行顺序。
public class Main { { System.out.println("Inside instance initializer 1."); } { System.out.println("Inside instance initializer 2."); } public Main() { System.out.println("Inside no-args constructor."); } public static void main(String[] args) { Main m = new Main(); } }上面的代码生成以下结果。
实例初始化程序不能有return语句。
静态初始化块
静态初始化块也称为静态初始化器。它类似于实例初始化块。
它用于初始化一个类。每个对象执行一个实例初始化器,而当类定义被加载到JVM中时,只对一个类执行一次静态初始化器。
我们需要在其声明的开头使用static关键字。
我们可以在类中有多个静态初始化器。所有静态初始化器都按文本出现的顺序执行,并在任何实例初始化器之前执行。
以下代码演示了何时执行静态初始化程序。
public class Main { private static int num; {// An instance initializer System.out.println("Inside instance initializer."); } // A static initializer. Note the use of the keyword static below. static { num = 2014; System.out.println("Inside static initializer."); } // Constructor public Main() { System.out.println("Inside constructor."); } public static void main(String[] args) { System.out.println("Inside main() #1. num: " + num); // Declare a reference variable of the class Main si; System.out.println("Inside main() #2. num: " + num); new Main(); // Create an object System.out.println("Inside main() #3. num: " + num); new Main();// Create another object } }上面的代码生成以下结果。



被折叠的 条评论
为什么被折叠?



