JAVA常见关键字及JDK 常用方法源码解读(持续更新...)

JAVA常见关键字及JDK 常用方法源码分析(持续更新...)

一、JAVA常见关键字

1、this 

        1)、常用于指向当前类对象本身(指向当前对象的本身),具体实现代码如下:

       

public class Student {
    private String name = "默认值1";

    public Student(){
        System.out.println("姓名:"+name);
    }

    public String getName(String name){
        this.name = name;
        return this.name;
    }

}
public class Main1 {
    public static void main(String[] args) {
        Student student = new Student();
        String name = student.getName("张三");
        System.out.println("返回结果:"+name);
    }
}
姓名:默认值1
返回结果:张三

Process finished with exit code 0

 this.name 指向的是private 定义的成员变量name,而不是形参name

       2)、this 调用本类构造函数,代码如下:

       

public class Student {
    private String name = "默认值1";

    public Student(String name){
        System.out.println("姓名:"+name);
    }
    public Student(String name, int age){
        this(name);//调用具有相同形参的构造方法
        System.out.println("年纪:"+age);
    }
    public String getName(String name){
        this.name = name;
        return this.name;
    }
}
public class Main1 {
    public static void main(String[] args) {
        Student student = new Student("李四", 20);
        String name = student.getName("张三");
        System.out.println("返回结果:"+name);
    }
}
姓名:李四
年纪:20
返回结果:张三

Process finished with exit code 0

      this另外一个作用就是调用本类中构造函数(同super,后续再讲)

      另外,this只能在类中的非静态方法中使用,静态方法和静态的代码块中绝对不能出现this。

2、super

      调用父类构造函数,代码如下:

      父类:

public class Class1 {
    public Class1(){
        System.out.println("父类无参构造函数C");
    }
    public Class1(String cname){
        System.out.println("班级是:"+cname);
    }
}

     子类:

public class Teacher1 extends Class1{
    public Teacher1(){
        super();
        System.out.println("调用父类无参构造函数成功T");
    }
    public Teacher1(String cname){
        super(cname);
        System.out.println("调用父类有参构造函数成功K");
    }
}
public class Main1 {
    public static void main(String[] args) {
       Teacher1 teacher1 = new Teacher1();
       Teacher1 teacher2 = new Teacher1("精英班");
    }
}

     结果:

父类无参构造函数C
调用父类无参构造函数成功T
班级是:精英班
调用父类有参构造函数成功K

Process finished with exit code 0

     

    可以看出,super可实现调用父类的无参或有参构造函数

super和this的异同:

  • super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句) 
  • this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句)
  • super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名    super.成员函数据名(实参)
  • this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
  • 调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。
  • super()和this()类似,区别是,super()从子类中调用父类的构造方法,this()在同一类内调用其它方法。
  • super()和this()均需放在构造方法内第一行。
  • 尽管可以用this调用一个构造器,但却不能调用两个。
  • this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
  • this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
  • 从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。

3、final  最终、不可变

     final在Java中是一个保留的关键字,可以声明成员变量、方法、类以及本地变量。一旦你将引用声明作final,你将不能改变         这个引用了,编译器会检查代码,如果你试图将变量再次初始化的话,编译器会报编译错误。例子如下:

     1)、修饰变量,变量不可改变

       

       提示:Cannot assign a value to final variable 'i' :不能为最终变量'i'赋值。被final修饰的变量初始值是什么,调用时不能重新赋值

      2)、修饰方法,不能被子类重写

        

        

        Class1 父类final 修饰的方法ftest() 不能被override重写

     3)、修饰类,类不可被继承

        

        

        final 修饰的类不能被继承

        网上也有这样解释不可变,挺有道理:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的。不能改变状态的意思是,不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。

二、JDK 常用方法源码分析

1、String 源码分析

      谈到String,最长想到的是String 赋值后不可变,即变量不可变,这时肯定能想到上文中提到的final修饰的变量不可变原理。

创建一个String对象,查看源码可知,String类确实是被final修饰了。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

可以发现,String类被final修饰,导致不可被继承。细心的同学会发现,同样final还修饰了一个字符数组变量 value[],Java中的String其实就是对字符数组的封装,所以导致String 创建后是不可变的,至于为什么要设计为不可变,那就涉及到内存、同步、数据结构相关方面知识。简单分析:

                                                

          先看这张图,当创建一个字符串对象时,如果字符串值已经存在于常量池里面,则不会再创建一个新的对象,而是引用已经存在的对象,也就是以下情况时。

String st1 = "abcd";
String st2 = "abcd";

  这里涉及到一个字符串常量池稍作解释:

          字符串常量池是java堆内存中一个特殊的存储区域,JVM(java 虚拟机)为了提高性能和减少内存开销,在实例化字符串常量时进行了一些优化,单独开辟一个字符串常量池,创建字符串常量时,首先判断字符串常量池是否存在该字符串,如果有则直接返回引用实例,不存在,则该字符串放在常量池中。

要实现字符串常量池的前提是,必须保证字符串不可变,不然数据共享时就会产生冲突。 同样,字符串的不可变保证了对应的hashcode永远不变,每次在使用一个字符串的hashcode的时候就不需要重新计算一次,提高了效率。     

    /** Cache the hash code for the string */
    private int hash; // Default to 0

  (译:缓存字符串的散列码)

 另外,不可变对象是线程安全的,多个线程共享时,无需做同步处理

 总结来讲,String 设计成不可变,提高了效率和安全性

 下面再调试看看String 究竟是如何赋值的:

                    

猜你喜欢

转载自blog.csdn.net/qq_29473881/article/details/82384062