JAVA-this关键字JAVAsuper关键字JAVA-static修饰符和final以代码块内部类和枚举
今日学习和总结
1:this关键字详解
作用:
1:在构造器中this关键字有指向成员变量
2:在方法中this关键字指向方法调用者
3:在当前类中调用其他非static修饰的方法
1:在构造器中指向当前类成员变量 public class Animal{ private String name; private int age; //演示一下构造器互调 public Animal(){ this("name",128); //此时就代表找个构造器已经初始化了名字找个成员变量但是必须和本类其他构造器形参一样this内 } public Animal(String name,int age){ this.name=name; this.age = age; } } 2:在方法中就是指向当前调用者 public boolean equal(Objec obj){ //此时this指向的就是他的调用者 return (this==obj); } 3:在本类前调用方法不加this 其实就是默认有一个this其实就是可以省略 但是不推荐省略 public class Animal{ public void speak(){} public void eat(){ this.speak(); } }
this本质:其实就是解决了成员变量和局部变量的二意性,和构造器重载互调
1:super关键字详解
作用:
1:指向父类构造器(或者访问父类构造器)
2:在子类中访问父类被覆盖的方法使用super
1:指向父类构造器 public class Animal{ private String name; private int age; public Animal(String name,int age){ this.name = name; this.age = age; } //方法 public void speak(){ System.out.println(我是一只动物); } } //继承动物类的猫类 public class Cat extends Animal{ //构造器调用父类构造器 //每个构造器第一行都会先调用父类的无参数构造器 然后要是再子类创建一个无参数构造器时 就会调用父类的无参数构造器 要是父类没有那么就会报错 其实这就是javabean规范规定的原因 public Cat(){} public Cat(String name,int age){ super(name,age); } 2:覆盖父类方法 并在方法内方法父类方法 public void speak(){ super.speak(); System.out.println("我是一只动物"); } }
3:static修饰符详解
作用:让static修饰的方法或者字段直接属于类
static 修饰的方法直接使用类名调用就好
注意:static 不能使用super和this
因为:static是类级别的 然后this和super是对象级别的不是一个重量级没办法使用
public class Animal(){ //用static修饰字段 private static String name; //用static修饰方法 public static void speak(){ System.out.println("我是静态的方法"); } } //创建一个测试方法 public static void main(String[] args){ System.out.println(Animal.name); //null 因为没赋值 Animal.speak();//会打印我是一个静态类 }
内存分析一下
static 修饰的字段和方法存在于方法区内部
对象调用static修饰的字段和方法时 就是先调用堆中的引用地址 然后再调用方法区的引用地址 因为所有static修饰的都是属于类的 所以无论是对象访问还是类名访问其底层都是使用类名访问
static成员变量在被加载的时候存在在方法区内被所有成员共享
实例成员和类的成员访问规则
static修饰的:直接用类名调用就好(类成员) 对象也可以方法但是底层还是类名访问的
无static修饰的:使用对象调用
如果要记录一些数据 就需要用static修饰字段
然后要是想创建一个对象记录数字就+1可以再构造器内++静态字段 就好了
4:final修饰符详解
作用:将当前的字段和方法设置为最终的
1:final修饰类表示当前类不能有子类
1:final修饰的方法作为最后一个方法不能被子类覆盖
2:final修饰的字段 引用类型不可以被改变引用地址 基本类型不可以被改变值
1:final修饰的累不能有子类 final public class Animal(){} public class Dog extends Animal(){} //此行语法报错 2:final修饰的方法不能被子类覆盖 public class Animal(){ final public void speak(){ } } public class Dog extends Animal(){ //覆盖父类方法 public void speak(){} //此行语法报错 } 3:final修饰的变量表示是最终的不能被改变 3.1基本数据类型变量 final int age = 18; age = 20; //此行语法报错 3.2引用数据类型 的引用地址不可以被改变 final Dog d = new Dog(); d.setAge(5); //引用类型被final修饰了 内值可以被改变 d = new Dog();//但是引用地址一定不可以被改变
5:代码块和匿名内部类
1:静态代码块
2:初始化代码块
3:局部代码块
public class Animal{ 1:静态代码块
seatic{ 在类被加载进入虚拟机时 就会初始化一次 仅一次 } 2:初始化代码块 { 在创建一个对象的时候就会执行一次 } public Animal(){} public static void main(String[] args){ 3:局部代码块 { 顺序执行 } } } 三个代码块的执行顺序 static 静态代码块
主方法
初始化代码块
构造器
初始化代码块
构造器
内部类和匿名类
1:内部类
对于内部类每一个都会加载一个字节码文件
静态的:就直接用外部类名调用就好了(外部类名$内部类名)
实例的:就是用外部类的对象调用(外部类名$内部类名)
局部的:暂时不会(外部类名$数字内部类名)
匿名:适合仅仅使用一次的内部类 (外部类名$数字)
class Outer{ class innter{ 此时就是内部类 } }
2:匿名内部类
//只执行一次的类
语法:new 父类/接口(){
----- 内部类类体
};
public class Animal(){ //创建一个方法 public void speak(){} } //创建一个动物类 public class Dog (){ public static void tt(){ //创建一个匿名内部类 其实就是new一个对象后面跟一个代码块 Animal a = new Animal{ //在此方法里面复写两个方法 public void speak(); //继承复写方法 public void say(){}; //代码块自定义 } a.speak(); //没问题 a.say(); //此时报错为什么 } }
为什么a.say()会报错: 因为内部类没有名字也就没有实例你怎么去调用 为什么a.speak()可以呢 因为他算是匿名类的继承 原类里面是有找个方法的 所以可以调用
那么怎么可以调用匿名类里面的自己定义的方法呢
new Animal{ //在此方法里面复写两个方法 public void speak(); //继承复写方法 public void say(){}; //代码块自定义 }.say(); //这样就可以了 实实现接口也是相同的原理一样的
其实匿名内部类也可以访问父类的方法和父类构造器的 怎么访问呢 其实就是在new 对象的时候在形式参数里面加上一段父类构造器内的内容就好
那么问题来了 可以加其他的字符串并使用吗
答案当然是可以的: 但是要在字符串前加入final 像这样final String name;如果要是不适用那么其实也可以不用final
public class Animal{ protected String name="老zi"; public Animal (String name){ this.name = name; } public void speak(){ Systm.out.println("我是"+name+"的方法"); } } public class Test{ public static void tt(){ new Animal("弟zi"){ System.out.println("内部类,匿名类,实例方法"); System.out.println(super.name); //此时是被匿名类修改过的名字 弟子 }; } }
总结:匿名内部类只可以使用一次 可以初始化构造器 可以访问父类的非private修饰的字段和方法 之后对象实体也可以调用匿名内部类里的方法;
6:枚举类的定义使用
作用:是得到一个安全不可改变的常量
声明常量对象A ==等价于 Public static final 类名 常量名 = new 类名();且枚举类都私有化构造器了 所以十分安全
//语法 public enum 枚举类名{ 常量对象A,常量对象B,常量对象C; } 枚举常量其实就是一个对象 但是有值 然后调用它就使用static调用就好
调用方法
一个接收类型 变量 = 类名.枚举类名.方法名(); 接收类型为方法的返回值类型
本文地址:https://blog.csdn.net/aYU8366/article/details/108025409
上一篇: springboot设置redis全局锁