final
【1】final成员变量表示常量,只能被赋值一次,赋值后值不可以在更改
private final int a=5;
//此时的a的值是固定的,无法被改动
【2】final修饰引用数据类型的时候,对其初始化之后就不能让其指向其他的对象
final Hello hello=new Hello();
hello =new Hello();
//Hello类初始化一个对象hello后
//hello是对象名,指向堆中的一个对象地址
//让hello等于new Hello()是相当于
//在堆中重新开辟地址存放新的对象,hello这个对象名指向的地址变化
//这是不对的
【3】final修饰引用数据类型时对象的内容是可以发生改变的,但是句柄所指向的地址不能发生改变
public static void main(String[] args) {
final Hello hello=new Hello();
hello.setName("kim");
hello.setAge(24);
System.out.println(hello.toString());
}
//输出
hello [name=kim, age=24]
public static void main(String[] args) {
final Hello hello=new Hello();
hello.setName("park");
hello.setAge(22);
System.out.println(hello.toString());
}
//输出
hello [name=park, age=22]
//这是因为我们在new了一个对象后,在堆中开辟了一个地址存放数据
// 在我们修改内部元素的时候,对象名hello指向的地址未发生改变
//所以是允许的
【4】final修饰类是不能被继承的
//父类
public final class Animal {
private String name;
private int age;
public void name() {
System.out.println("你好");
}
}
//子类
public class Dog extends Animal{ //报错 无法继承
public static void main(String[] args){
System.out.println("继承你好");
}
}
/*如果说整个类都是final(在它的定义前冠以final关键字),就表明自己不希望从这个类继承,
或者不允许其他任何人采取这种操作。
换言之,出于这样或那样的原因,我们的类肯定不需要进行任何改变;
或者出于安全方面的理由,我们不希望进行子类化(子类处理)。*/
【5】final修饰的方法时不能被子类重写 子类只能够继承父类public类型的方法,也就是说我们可以重写父类private final类型修饰的方法。严格意义上不能叫做重写,应该叫重新定义。
//父类
public class Animal{
private String name;
private int age;
private final void name() {
System.out.println("动物");
}
public final void age() {
System.out.println(15);
}
}
//子类
public class Dog extends Animal{
private final void name() {
System.out.println("狗");
}
public void age() {
System.out.println(20);
}//报错
public static void main(String[] args) {
test test=new test();
test.name();
test.age();
}
}
//输出
狗
在父类中的方法里,用public final修饰的方法可以被子类调用,但因为方法为final类型所以无法重写
而private final修饰的方法因为本身是private 无法被子类调用,又是final,所以在子类中的同名方法其实跟父类没关系 ,可以算是重写方法
static
static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。
static修饰的一切都放在静态方法区中
【1】静态方法中不能访问非静态成员变量和非静态成员方法
如果想要访问,有两种解决方法
①new一个对象,通过对象来调用
②把非静态方法变为静态(添加static关键字)
public class hello {
static int a=10;
int b=5;
public static void name1(int a) {
hello test=new hello();
test.name();
}
public void name() {
a=16;
System.out.println(a);
}//或者把该方法改为static修饰
public static void main(String[] args) {
hello.name1(a);
}
}
//输出
16
【2】非静态方法中可以访问到静态成员变量和方法
public class hello {
static int a=10;
static int b=5;
public static void name(int a) {
a=15;
System.out.println(a);
}
public void name1() {
a=16;//访问到静态成员变量
name(a);//访问到静态成员方法
}
public static void main(String[] args) {
hello test=new hello();
test.name1();//此处是静态访问非静态
}
}
//输出
15
【3】static修饰的变量被称为静态变量,它属于类,而不属于某个对象,因此所有对象的static变量指向的是同一块静态方法区中的内存地址。
public class hello {
static int a=10;
public static void main(String[] args) {
hello test = new hello();
System.out.println(test.a);
hello text = new hello();
System.out.println(text.a);
text.a = 20;
System.out.println(test.a);
System.out.println(text.a);
}
}
//输出
10
10
20
20
【4】两种调用static方法的方式
①类.方法名 类.变量名
②对象名.方法名
public class hello {
static int a=1;
public static void name(int a) {
a=10;
System.out.println(a);
}
public static void main(String[] args) {
hello.a=2;//类名.变量名
System.out.println(a);
hello.name(a);//类名.方法名
hello hello1 =new hello();
hello1.name(a);//对象名.方法名
}
}
//输出
2
10
10
【5】static块
static块级元素只会在类加载的时候执行一次
一个类加载从上往下先执行静态的赋值语句或初始化块
遇到new的时候就从上往下执行非静态的赋值语句和初始化块
最后执行构造函数如果没有new就不输出构造函数