API底层的概述—Object类方法概述—String字符串常量池-equal方法的重写

API————》Application Programming Interface(提供一系列的接口以及接口下的类)
API里提供的所有方法要么被protected修饰,要么被默认public进行修饰。
Public:同包的本类,子类,非子类,非同包的子类,非子类都可以访问。
Protected: 同包的本类,子类,非子类,非同包的子类可访问,非子类不可以访问。
默认修饰符:只有同包的可以访问。非同包的不可访问。
Private:只有本类可访问。其余的不能访问。

java:(原生包)
lang包:当程序启动时必须要加载的信息(核心内库)
util包:提供了大量的工具类,接口,信息等,来去操作类/接口的(工具包
IO包:做数据传输
math包:提供简单的数学运算
net包:网络传输
nio包:高并发
security包:安全
sql包:操作数据库
text包:格式化
time包:时间和日期
javaX(扩展包)
org(第三方厂商提供的包在这里插入代码片)

Object类:
Object类是java的顶级父类,每个类默认继承Object类。–Class A extends B{}, Class B extends Object{},定义的每个类都能拿到object的信息

  1. 只有无参构造:Constructor and Description ----Object()
  2. 没有属性,所以没有有参构造,智能调用其中的方法
  3. 重要方法:
    4. clone():将对象的属性值赋值到新符对象中,两者是不同的地址空间,前提–克隆类需要实现Cloneable接口对象才能实现克隆的结果,protected修饰符的特点,子类一定要在本类中使用
    5. java底层的操作:只要是类实现的接口,那么接口将会给实现的类默认添加一个标记,类产生的每个对象都带有这个标记,当做某种操作的时候,JVM检测出带有标记的对象,则会正常进行该对象接口的操作。
    4. finalize():通知系统进行垃圾回收(GC)
    5. getClass():返回的是类的全限定类名—》包名+类名----可以获取全限定类名的操作
    6. toString():拼接对象地址值:为了获取的是对象的属性值需要重写toString()----重写的方法
    public static void main(String[] args) {
        ObjectDemo3 od = new ObjectDemo3();
        //od对象传入到底层里的valueof()方法中去调用object中的toString方法()
        System.out.println(od);
        //od对象直接调用object中的tostring()来拼接地址值
        System.out.println(od.toString());

        //创建对象
        Person p = new Person();
        p.age=10;
        p.gender='男';
        p.name="tom";

        System.out.println(p);//底层默认进行调用valueof---调用toString()方法进行字符串的拼接
    }

null在底层表示地址指针不指向任何的地址空间,引用类型的默认值所以可以使用 == 运算符进行相等的判断
基本数据类型进行比较的时候,比较的是字面量是否相等,四类八种
引用数据类型,进行比较的是地址值—》equals(Object obj)–做两件事:先进行对象的地址值是够相等,在进行比较属性值是否相等

自己重写equals的方法:

package cn.tedu.api;

import java.util.Objects;

public class ObjectDemo4 {

    public static void main(String[] args) {
        Student s1 = new Student();
        s1.name="张三";
        s1.age=10;
        s1.gender='男';
        Student s2 = new Student();
        s2.name="张三";
        s2.age=10;
        s2.gender='男';
        //Object类型equal方法是根据对象的地址值来判断是否相等的
        //Student s2=s1;//null在底层表示地址指针不指向任何的地址空间,引用类型的默认值
        System.out.println(s1.equals(s2));
    }
}
class Student{
    //属性
    String name;
    int age;
    char gender;

    public boolean equals(Object obj){
        if (this==obj){
            return true;
        }
        if (obj==null){
            return false;
        }
        //判断两个对象的类型是否一样
        //把所有类型不同的情况都进行排除
        if (this.getClass()!=obj.getClass()){
            return false;
        }
        //执行到此低,说明,两个对象在逻辑上一致的
        //但是从语义上来说,还需要进行强转
        Student s= (Student) obj;
        //比较对象属性值
        if(this.age!=s.age){
            return false;//已经年龄相等了
        }
        //比较两个对象的性别,
        if (this.gender!=s.gender){
            return false;
        }
        //比较两个对象的姓名--地址值的形式
        //name的对象是String类的重写方法toString()--先比较对象的地址,然后再进行比较对象的内容,两者都是null的情况也要进行排除
        if (this.name==s.name||this.name!=null&&this.name.equals(s.name)){
            return true;
        }
        //两个对象的name不相等
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, gender);
    }
}
``

`
**字符串常量池的出现:**
常量池:JVN为每个已经加载的类型维护一个常量池,常量池就是这个类型用到的常量的有序集合,包括直接常量(基本类型,String类型)和其他类型、方法、字段的符号引用,池中的数据和数组一样通过索引进行访问

 1. java设计者为String提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么?
 2. 字符串的分配,和其他的对象分配一样,耗费高昂的时间和代价,作为最基础的数据类型,大量创建字符串,极大程度的影响程序的性能
 3. JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化
 4. 为字串开辟了一个字符串常量池,类似于缓存区
 5. 创建字符串常量的时候,首先坚持字符串常量是否存在该字符串,存在该字符串,返回引用实例,不存在,实例化该字符串并放入常量池中
 6. 实现的基础:实现该优化的基础是因为字符串是不可变的,可以不用担心数据冲突进行共享
 7. 运行的时候实例创建的全局字符串常量池中有一个表,总是为池中每个唯一的字符串对象维护一个引用,意味着他们总是引用着字符串常量池中的对象,所以,在常量池中的这些字符不会被垃圾收集器回收
 代码:从字符串常量池中获取相应的字符串

  String str1 = “hello”;

  String str2 = “hello”;
字符串常量池存在哪里?---->方法区-----方法区中的的信息在程序中的永远是唯一的,不可变的如:class  static变量

面试题:String str4 = new String(“abc”) 创建多少个对象?
	

		 1.解答如下:在常量池中寻找是否存在:abc对象
		 2. 有则返回对应的引用实例,没有则在常量池中创建该实例对象
		 3. 在堆中出现一个 new String("abc")对象
		 4. 将对象在堆中的地址值赋值给一个引用,所以常量池中没有“”abc“”字面量则创建两个对象,否则创建一个对象,以及创建一个引用

变式题:		String str1 = new String("A"+"B") ; 会创建多少个对象? 
					String str2 = new String("ABC") + "ABC" ; 会创建多少个对象?

 str1:  51. 字符串常量池:A,B,AB     3
 			2.  堆中:new String(“A”+"B"1
 			3. 栈中:引用  Str1                     1
str2:   31. 字符串常量池:原本有一个   ABC,因为常量池中存在该对象的创建    1
			2. 堆中:new String"ABC"1
			3. 栈中:引用 :1

通过new 操作符创建的字符串对象不指向字符串池中的任何对象,但是可以通过使用字符串的intern()方法来指向其中的一个,该方法返回一个保留池字符串,就是一个在全局字符串常量池中有了一个入口,如果以前没有在全局字符串池中,那么它就会将该字符串添加到里面


**注意:基本类型的变量和常量:变量和引用存储在栈中,常量的存储在常量池中*--->常量存在于方法区中,堆中的大小和周期不稳定,不适合进行存储相关的变化*
			
			**常量**
					字符串常量,基本类型常量,静态常量,final修饰的常量
   

版权声明:本文为qq_43349161原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。