1. static 关键字的使用
1.1 静态变量
static 声明的属性是所有对象共享的。所以,也把用 static 类型声明的变量,称之为“类变量”。
用 static 方式声明的属性,也可以用类名直接访问。如下:
Person.city = “Beijing” ;
1.2 静态方法
static 既可以在声明变量时使用, 也可以用其来声明方法, 用它声明的方法有时也被称为“类方法”。
package javalearning;
class Student {
String name;
int age;
private static String city = "Beijing";
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void print() {
System.out.println("Name: " + name + " Age: " + age + " City: " + city);
}
public static void setCity(String c)
{
city = c ;
}
}
public class TestStatic {
public static void main(String[] args) {
Student stu1 = new Student("A", 20);
Student stu2 = new Student("B", 19);
stu1.print();
stu2.print();
Student.setCity("XiaMen");
System.out.println("City has been modified! ");
stu1.print();
stu2.print();
}
}
//运行结果:Name: A Age: 20 City: Beijing
Name: B Age: 19 City: Beijing
City has been modified!
Name: A Age: 20 City: XiaMen
Name: B Age: 19 City: XiaMen
在使用 static 类型声明的方法时需要注意的是:
如果在类中声明了一 static类型的属性。则此属性既可以在非 static 类型的方法中使用,也可以在 static类型的方法中使用。
但用 static 类型的方法调用非 static 类型的属性时, 则会出现错误。
1.3 理解 main()方法
我们知道,如果一个类要被 Java 解释器直接装载运行, 这个类中必须有 main()方法。
那为什么main()方法必须要声明成public和static的呢?
由于 Java 虚拟机需要调用类的 main()方法,所以该方法的访问权限必须是 public。
又因为 Java 虚拟机在执行 main()方法时不必创建对象,所以该方法必须是 static 的。
String[] args(或者String args[])的行参表示该方法接收一个 String 类型的数组参数,该数组中保存执行 Java 命令时传递给所运行的类的参数。
向Java中传递参数可以用如下命令:
java 类名称 参数 1 参数 2 参数 3
下面我们用一个例子来说明:
public class TestMain {
/*
* public:表示公共方法
* static:表示此方法为一静态方法,可以由类名直接调用
* void:表示此方法无返回值
* String[] args:接收运行时参数
*/
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("You must input at least 1 parameter!");
} else {
for(int i =0; i < args.length; i++)
System.out.println(args[i]);
}
}
}
命令行中执行:
javac TestMain
java TestMain first second
结果是:
first
second
1.4 静态代码块
一个类可以使用不包含在任何方法体中的静态代码块,当类被载入时, 静态代码块被执行,且只执行一次,
静态代码块经常用来进行类属性的初始化。
静态代码块优先于静态方法,因此,静态代码块可以为静态属性初始化。
如下例:
class Student {
public Student() {
System.out.println("1. class Student -> Student()");
}
static {
System.out.println("2. class Student -> static code block");
}
}
public class TestStaticDemo {
static {
System.out.println("3. class TestStaticDemo -> static code block");
}
public static void main(String[] args) {
System.out.println("4. class TestStaticDemo -> main start");
new Student();
new Student();
}
}
//运行结果:
3. class TestStaticDemo -> static code block
4. class TestStaticDemo -> main start
2. class Student -> static code block
1. class Student -> Student()
1. class Student -> Student()
2. 构造方法的私有
方法依实际需要可分为 public 与 private。 同样的,构造方法也有 public 与 private之分。
到目前为止,所使用的构造方法均属于 public,它可以在程序的任何地方被调用,所以新创建的对象也都可以自动调用它。
如果构造方法被设为 private,则无法在该构造方法所在的类以外的地方被调用。
我们来看一个挺有趣的例子:
class Student {
String name;
private Student() { //将构造方法声明为private的
name = "Y";
}
//标记为final的,表示不能再重新实例化
private static final Student stu = new Student();
public static Student getStu() {
return stu;
}
}
public class TestMain {
public static void main(String[] args) {
//这里因为Student类的构造方法是private的,不能通过new实例化,只能使用 类名.方法名 静态引用。因此要求getStu是静态的。
Student s = Student.getStu();
System.out.println(s.name);
}
}
首先Student类中的构造方法被声明成了private型的,因此只能Student类内部访问。
所以需要在该类的内部实例化一个对象stu,并且在公共方法getStu()中返回,而getStu()是static的,所以stu的实例化也只能是static的。
3. 对象数组的使用
1、 声明类类型的数组变量,并用 new 分配内存空间给数组。
2、用 new 产生新的对象,并分配内存空间给它
如:
Student stu[] = new Student[3];
stu[0] = new Student () ;
stu[1] = new Student () ;
stu[2] = new Student () ;
或者可以采用静态方式初始化对象数组:
Person p[] = {new Person(),new Person(),new Person()} ;
4. 内部类
内部类即在类的内部定义的类。如果在类 Outer 的内部再定义一个类 Inner,此时类 Inner 就称为内部类,而类 Outer 则称为外部类。
内部类可声明成 public 或 private。当内部类声明成 public 或 private 时,对其访问的限制与成员变量和成员方法完全相同。
用 static 声明的内部类则变成外部类,但是用 static 声明的内部类不能访问非 static 的外部类属性。
4.1 在类外部引用内部类
内部类也可以通过创建对象从外部类之外被调用,只要将内部类声明为 public 即可。
看下面的例子:
class Outer {
int score = 95;
void inst() {
Inner in = new Inner();
in.display();
}
public class Inner {
void display() {
System.out.println("Score: " + score);
}
}
}
public class TestInner {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner(); //注意这里的写法,先要实例化一个Outer对象,然后用这个对象new一个Inner
inner.display();
}
}
执行javac TestInner.java
编译上述代码会产生3个文件:Outer.class,Outer$Inner.class,TestInner.class
4.2 在方法中定义内部类
内部类不仅可以在类中定义,也可以在方法中定义内部类。有的书称为方法内部类,也有的称为本地内部类。
如上例,我们吧Inner的类定义挪到inst()方法中。如下:
class Outer {
int score = 95;
void inst() {
class Inner { //注意,这里不能再声明为public的
void display() {
System.out.println("Score: " + score);
}
}
Inner in = new Inner();
in.display();
}
}
public class TestInner2 {
public static void main(String[] args) {
Outer outer = new Outer();
outer.inst();
}
}
(注:这里的Outer$1Inner就是表示Inner是定义在Outer的方法里的内部类。)
关于方法内部类的特点,在网上找到了几点。
-------------------
(1)、方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。
(2)、方法内部类对象不能使用该内部类所在方法的非final局部变量。
因为方法的局部变量位于栈上,只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,局部变量成为历史。
但是该方法结束之后,在方法内创建的内部类对象可仍然存在于堆中!
例如,如果对它的引用被传递到其他某些代码,并存储在一个成员变量内。
正因为不能保证局部变量的存活期和方法内部类对象的一样长,所以内部类对象不能使用它们。
-------------------
方法内部类的特点:
(1):仅在定义了它们的代码块中是可见的;
(2):可以使用定义它们的代码块中的任何本地final变量;
(3):本地类不可以是static的,里边也不能定义static成员。
(4):本地类不可以用public、private、protected修饰,只能使用缺省的。
(5):本地类可以是abstract或者final的。
(参考:http://www.csdn123.com/html/blogs/20130810/51071.htm)
4.3 匿名内部类
匿名内部类也是比较常见的内部类。但是由于使用匿名内部类必须继承一个父类或实现一个接口。
以后再介绍。
以上内容参考:
Java基础教程 (http://wenku.baidu.com/view/d19061631ed9ad51f01df2a9.html) 作者不祥