final关键字
final 最终的 可以修饰类、方法、属性、变量
final修饰变量,则变量变成常量,只能被赋值一次,终身不变。
final修饰类,则该类不能被继承,但是它可以继承其他类,它本身还是个类。并且可以实例化对象,调用方法。
final修饰方法,则该方法不允许被覆盖(重写)
final修饰成员变量,只能在创建对象之前给它赋值,可以在类中赋值,也可以在构造方法中赋值,但是不能用set方法赋值,set方法是在创建对象之后给变量赋值。
final修饰局部变量,若是基本数据类型,则其值不能被改变;若是引用数据类型,则引用类型的地址值不能被改变,但是,对象在堆内存中的值是可以改变的。
static关键字
我们基于一个类可以创建多个该类的对象,每个类都拥有自己的成员,互相独立,然而在某些时候我们更希望该类所有的对象共享一个成员,此时用到static
Java中被static修饰的成员称为静态成员或类成员,它属于整个类所有的,不是某个对象所拥有的,即被类的所有对象所共享。静态成员可以使用类名直接访问,
也可以使用对象访问。鉴于它属于整个类,所以建议用类名调用。
调用格式:
类名.静态成员变量名
类名.静态成员方法名(参数)
class Demo {
public static int num = 100;
public static void method(){
System.out.println("静态方法");
}
}
class Test {
public static void main(String[] args) {
System.out.println(Demo.num);
Demo.method();
}
}
注: 静态内容是优先于对象存在,只能访问静态,不能使用this/super。静态修饰的内容存于静态区。(静态区在方法和内容共享区)
在静态方法中,可直接调用同类中的静态成员变量和静态成员方法,但不能调用非静态成员。若执意调用则需要创建类的对象去访问非静态变量或者非静态成员方法。
在普通成员方法中,可直接访问同类中的非静态变量和静态变量。
静态方法中是没有this或super关键字的。静态是随着类的加载而加载的,this或super是随着对象的创建而存在的。
定义静态常量
public static final 数据类型 变量名 = 值;
注:接口中的每个成员变量都默认使用public static final修饰。
所有接口中的成员变量已是静态常量,由于接口没有构造方法,所以必须显示赋值。可以直接用接口名访问。
interface Inter {
public static final int COUNT = 100;
}
访问接口中的静态变量
Inter.COUNT
匿名对象
匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量。
创建一个普通对象 Person p = new Person();
创建一个匿名对象 new Person();
匿名对象的特点:
1、创建匿名对象直接使用,没有变量名。
new Person().eat() //eat方法被一个没有名字的Person对象调用了。
2、普通对象是将地址赋给变量,可以重复使用。
3、匿名对象在没有指定其引用变量时,只能使用一次。
new Person().eat(); 创建一个匿名对象,调用eat方法
new Person().eat(); 想再次调用eat方法,重新创建了一个匿名对象 因为每new一次就会开辟一块新的内存地址
4、匿名对象可以作为方法接收的参数、方法返回值使用
内部类
内部类就是定义在另一个类里面的类,与之对应,包含内部类的类就是外部类
作用:内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类
内部类的方法可以直接访问外部类的所有数据,包括私有数据
成员内部类
定义在外部类中的成员位置。与类中的成员变量相似,可通过外部类对象进行访问
class 外部类 {
修饰符 class 内部类 {
//其他代码
}
}
访问方式 外部类名.内部类名 变量名 = new 外部类名().new 内部类名();
public class Outer{ //外部类
private int a=99;
public class Inner{ //内部类 处于外部类的成员变量的位置
int b=2;
public void test(){
System.out.println("访问外部类中的a:"+a);
System.out.println("访问内部类中的b:"+b);
}
}
public static void main(String[] args){
Outer.Inner i =new Outer().new Inner();
i.test();
}
}
局部内部类
定义在外部类方法中的局部位置。与访问方法中的局部变量相似,可通过调用方法进行访问
定义格式
class 外部类 {
修饰符 返回值类型 方法名(参数) {
class 内部类 {
//其他代码
}
}
}
访问方式 :在外部类方法中,创建内部类对象,进行访问
public class Outer {
public void out(){
class inner{ //局部内部类
public void in(){
System.out.println("这是局部内部类的方法");
}
}
inner i=new inner(); //在外部类的方法中 创建内部类对象
i.in();
}
}
public class Test1 {
public static void main(String[] args) {
Outer o=new Outer();
o.out();
}
}
匿名内部类
是局部内部类的一种
作用:匿名内部类是创建某个类型子类对象的快捷方式。
格式:
new 父类或接口(){
//进行方法重写
};
new smoking(){
public void smoke() {
System.out.println("猴子抽大烟");
}
}.smoke();
使用匿名对象的方式,将定义子类与创建子类对象两个步骤由一个格式一次完成
静态内部类
静态内部类是static修饰的内部类,特点是:
1、静态内部类不能直接访问外部类的非静态成员,但是可以通过new 外部类().成员的方式访问
2、如果外部类的静态成员与内部类的成员名称相同,可通过类名.静态成员访问外部类的静态成员;如果名称不相同,则可通过成员名直接调用外部类的静态成员
3、创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名 = new 内部类();
public class Souter {
private int a=99;
static int b=1;
public static class Sinner{
int b=2;
public void test(){
System.out.println("访问外部类中的b:"+Souter.b);
System.out.println("访问内部类中的b:"+b);
}
}
}
public static void main(String[] args){
Sinner si =new Sinner();
si.test();
}
访问修饰符
public |
protected |
default |
private |
|
同一类中 |
√ |
√ |
√ |
√ |
同一包中(子类与无关类) |
√ |
√ |
√ |
|
不同包的子类 |
√ |
√ |
||
不同包中的无关类 |
√ |
1、要想仅能在本类中访问使用private修饰;
2、要想本包中的类都可以访问不加修饰符即可;
3、要想本包中的类与其他包中的子类可以访问使用protected修饰
4、要想所有包中的所有类都可以访问使用public修饰。
注意:如果类用public修饰,则类名必须与文件名相同。一个文件中只能有一个public修饰的类。
代码块
局部代码块是定义在方法或语句中
class Demo{
public static void main(String[] args) {
{
int x = 1;
System.out.println("普通代码块" + x);
}
int x = 99;
System.out.println("代码块之外" + x);
}
}
结果:
普通代码块1
代码块之外99
构造代码块是定义在类中成员位置的代码块
1、优先于构造方法执行,构造代码块用于执行所有对象均需要的初始化动作
2、每创建一个对象均会执行一次构造代码块。
public class Person {
private String name;
private int age;
//构造代码块
{
System.out.println("构造代码块执行了");
}
Person(){
System.out.println("Person无参数的构造函数执行");
}
Person(int age){
this.age = age;
System.out.println("Person(age)参数的构造函数执行");
}
}
class PersonDemo{
public static void main(String[] args) {
Person p = new Person();
Person p1 = new Person(23);
}
}
静态代码块是定义在成员位置,使用static修饰的代码块。
1、 它优先于主方法执行、优先于构造代码块执行,当以任意形式第一次使用到该类时执行。
2、该类不管创建多少对象,静态代码块只执行一次。
3、可用于给静态变量赋值,用来给类进行初始化。
public class Person {
private String name;
private int age;
//静态代码块
static{
System.out.println("静态代码块执行了");
}
}
A:一个类的静态代码块、构造代码块、构造方法的执行流程:静态代码块>构造代码块>构造方法
B:静态的内容随着类的加载而加载的,静态代码块优先执行
C:子类初始化之前先进行父类初始化。