文章目录
- static修饰成员变量
- static修饰成员方法
- static成员变量初始化
- 内部类
- static修饰成员变量
在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的,例如:当我们定义学生类时,要表示学生上课的教室,这个教室的属性并不需要每个学生对象中都存储一份,而是需要让所有的学生来共享,这时要定义一个所有对象共享的静态成员
public class Class {
private String name;
private String gender;
private int age;
private static String classRoom = "A123";
public static void main(String[] args) {
//静态成员变量可以直接通过类名访问
System.out.println(Class.classRoom);
Class c1 = new Class();
Class c2 = new Class();
Class c3 = new Class();
//也可以通过对象访问:但是classRoom是3个对象共享的
System.out.println(c1.classRoom);
System.out.println(c2.classRoom);
System.out.println(c3.classRoom);
}
}
以调试方式运行上述代码,然后在监视窗口中可以看到,静态成员变量并没有存储到某个具体的对象中
- static修饰成员方法
public class Class {
private String name;
private String gender;
private int age;
private static String classRoom = "A123";
public static void setClassRoom(String classRoom) {
Class.classRoom = classRoom;
}
public static String getClassRoom() {
return classRoom;
}
}
class TestClass{
public static void main(String[] args) {
System.out.println(Class.getClassRoom());
}
}
输出:A123
- static成员变量初始化
静态成员变量的初始化分为两种:就地初始化和静态代码块初始化
- 就地初始化就地初始化指的是:在定义时直接给出初始值
- 静态代码块初始化
class TestClass{
public TestClass() {
System.out.println("不带参数的构造方法");
}
public static String classes;
{
System.out.println("实例代码块");
}
static {
System.out.println("静态代码块");
}
public static void main(String[] args) {
TestClass testClass = new TestClass();
}
}
先执行了静态代码块,静态代码块在类加载的时候就会被执行,和代码顺序无关
当我们再执行一遍时,静态代码块不会再执行了,态代码块不管生成多少个对象,其只会执行一次
- 内部类
public class OutClass{
class InnerClass{
}
}
//OutClass是外部类
//InnerClass是内部类
注意事项:
- 定义在class 类名{}花括号外部的,即使是在一个文件里,都不能称为内部类
public class A{
}
class B{
}
//A和B是两个独立的类,彼此之前没有关系
- 内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件
public class Test {
public static void main(String[] args) {
System.out.println("hello");
}
class Test1{
public void test(){
}
}
}
根据内部类定义的位置不同,一般可以分为以下几种形式:
- 成员内部类(普通内部类:未被static修饰的成员内部类和静态内部类:被static修饰的成员内部类)
- 局部内部类(不谈修饰符)、匿名内部类(学习接口时介绍)
public class OutClass{
//成员位置定义:未被static修饰--->实例内部类
public class InnerClass1{
}
//成员位置定义:被static修饰--->静态内部类
static class InnerClass2{
}
public void method(){
//方法中也可以定义内部类--->局部内部类:几乎不用
classInnerClass5{
}
}
}
注意:内部类其实日常开发中使用并不是非常多,大家在看一些库中的代码时候可能会遇到的比较多,日常开始中使用最多的是匿名内部类
实例内部类
即未被static修饰的成员内部类
看四个问题:
- 如何获取实例内部类的对象?
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
public class Test {
//1:如何获取实例内部类的对象
OuterClass outerClass = new OuterClass();
//通过外部类对象的引用来调用内部类,可以把实例内部类当作外部类的一个成员
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
//两种写法都可
OuterClass.InnerClass innerClass2 = new OuterClass().new InnerClass();
}
class OuterClass{
public int data1;
int data2;
public static int data3;
public void test(){
System.out.println("OuterClass:test");
}
//实例内部类
class InnerClass{
public int data4;
int data5;
//public static int data6;
public void func(){
System.out.println("InnerClass:func");
}
}
}
2. 为何出错?
实例内部类中不能有static的成员变量,必须要定义的话要用final修饰
static是定义类的成员,类加载的时候就已经会被执行,而内部类需要通过对象的引用才能执行,所以会出错
final是常量,类似于C中的const,初始化之后是不能再修改的,编译之后已经定好了
3.外部类和内部类都有data1这个成员,调用时会打印哪个呢?
class OuterClass{
public int data1 = 1;
int data2 = 2;
public static int data3 = 3;
public void test(){
System.out.println("OuterClass:test");
}
//实例内部类
class InnerClass{
public int data1 = 4;
int data5 = 5;
public static final int data6 = 6;
public void func(){
System.out.println("InnerClass:func");
System.out.println(data1);
System.out.println(data2);
System.out.println(data3);
//System.out.println(data4);
System.out.println(data5);
System.out.println(data6);
}
}
}
访问的是内部类自己的成员
4.如果要在內部类中访问外部类中的相同的成员变量如何做?
这样是可以的,或者 在实例内部类中使用外部类的引用:
在实例内部类中使用外部类的引用写法:
System.out.println(OuterClass.this.data1);
静态内部类
被static修饰的内部成员类称为静态内部类
看两个问题:
1.如何获取静态内部类对象?
OuterClass2.InnerClass2 innerClass2 = new OuterClass2.InnerClass2();
class OuterClass2{
public int data1 = 1;
int data2 = 2;
public static int data3 = 3;
public void test(){
System.out.println("OuterClass:test");
}
static class InnerClass2{
public int data1 = 4;
int data5 = 5;
public static int data6 = 6;
public void func(){
System.out.println("InnerClass2:func");
}
}
public static void main(String[] args) {
OuterClass2.InnerClass2 innerClass2 = new OuterClass2.InnerClass2();
}
}
2. 静态内部类当中不能访问外部类的非静态成员,外部类的非静态成员需要外部类的对象的引用才能访问
如果要访问:
局部内部类
定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用,一般使用的非常少,此处简单了解下语法格式
public class Test {
//局部内部类:定义在方法体内部
// 不能被public、static等访问限定符修饰
public void method(){
class InnerClass{
public void methodInnerClass(){
System.out.println("hello");
}
}
//只能在该方法体内部使用,其他位置都不能用
InnerClass innerClass= new InnerClass();
innerClass.methodInnerClass();
}
public static void main(String[] args) {
//编译失败
Test.InnerClassinnerClass=null;
}
}