Java学习day014(Object、基本包装类型、String类、StringBuilder)

Object类的学习

在java,所有的类都是Object类子类

Object类是所有类的父类
在这里插入图片描述

-----Object.java
getClass(); 	// 获取字节码文件
hashcode();		// 对象的hashcode值
equals();		// 判断两个对象是否相等,使用的地址判断
finalize();		// 垃圾回收前自动执行的该方法

For example

package om.openlab.da14.object;

public class Test {
    public static void main(String[] args) {
        User u = new User();
        System.out.println(u.getClass()); // class om.openlab.da14.object.User
        System.out.println(u.hashCode()); // 2083562754
    }
}

class User {
}

native关键字

native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中

✨hashcode()

如果两个对象是同一个对象(地址相同),hashcode值肯定一样,
如果两个对象hashcode值相同,不一定是同一个对象

OpenJDK:提供了五种hashcode算法,其中有一种,直接返回内存地址
就是内存地址hash值,这句话不算错,但是不一定准确

注意:

如果两个对象的equals比较相等,hashcode肯定相等
如果两个对象的hashcode相等,equals不一定相等


final、finally、finalize()三者的区别

final

1、final修饰的class,代表不可以继承扩展。

2、final的方法也是不可以重写的。

3、final修饰的变量是不可以修改的。这里所谓的不可修改对于基本类型来来,的确是不可以修改。而对于引用类型来说,只能说不能重新赋值。也就是不能改变引用地址。但是作为引用类型,它内部所包含的内容如果不是final则可以随意修改

finally

提到finally,那么try-catch就逃不掉了。finally 则是Java保证重点代码一定要被执行的一种机制。最常用的地方:通过try-catch-finally来进行类似资源释放、保证解锁等动作

finalize

设计之初的作用就是:在CG要回收某个对象时,让这个对象有底气的大喊一声:“报告,我还能再抢救一下!”。但是也正是因为如此,JVM要对它进行额外处理。finalize也就成为了CG回收的阻碍者,也就会导致这个对象经过多个垃圾收集周期才能被回收。


对象拷贝

此处可以参考博客:
1.ava如何复制对象
2.java引用拷贝,对象浅拷贝,对象深拷贝
引用传递:
对象是没有拷贝,是同一个对象,拷贝的是栈内存(地址)


在java中,如果某个类需要调用Object的clone完成对象的拷贝,必须让该类实现

在java中,如果一个类要实现clone方法,必须要实现一个接口(Cloneable)

在java中,存在了一类接口,里面没有任何代码,标注接口!!!

浅拷贝:

Object类,提供的`clone`方法就是浅拷贝(对象)
在进行对象拷贝时候,仅仅完成了对象的第一层拷贝,如果该对象存在着子对象,则
不会拷贝子对象

深拷贝:

递归拷贝,会把所有的对象全部分离
1、让子对象也实现Cloneable接口,在父对象进行拷贝是,子对象也同时拷贝
2、通过序列化对象和反序列化来实现深拷贝

引用传递

package om.openlab.da14.copy;
public class Test {
    public static void main(String[] args) {
        User user2 = new User();
        user2.setUsername("第一");

        // user2的地址传递到user3中,对象没有拷贝,拷贝的是栈地址
        User user3 = user2;

        System.out.println(user2); // User{username='第一'}
        System.out.println(user3); // User{username='第一'}

        user2.setUsername("第二");
        System.out.println(user2); // User{username='第二'}
        System.out.println(user3); // User{username='第二'}
    }
}

class User {
    private String username;
    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                '}';
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
}

浅拷贝

package om.openlab.da14.copy;
public class User implements  Cloneable{ // 实现Cloneable接口
    private String username;
    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                '}';
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
-----
package om.openlab.da14.copy;
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        User user2 = new User();
        user2.setUsername("第一");

        User user4 = (User) user2.clone();

        System.out.println(user2 == user4); // false

        user4.setUsername("第二");
        System.out.println(user2); // User{username='第一'}
        System.out.println(user4); // User{username='第二'}
    }
}

基本类型包装类

想要知道 Java为什么需要包装类型 可以参考下面这篇博客
Java中有了基本数据类型,为什么还需要包装类型

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCHaracter
booleanBoolean

Integer类的概述和使用

Integer:包装一个对象中的原始类型int的值

方法名说明
public Integer(int value)根据int值创建Integer 对象(过时)
public Integer(String s)根据String值创建Integer对象(过时)
public static Integer valueOf(int i)返回表示指定的int值的Integer 实例
public static Integer valueOf(String s)返回一个保存指定值的Integer对象String

int 和 String的相互转换

基本类型包装类的最常见操作就是:用于基本类型和字符串之间的相互转换

1.int转换为String
public static String valueOf(inti):返回int 参数的字符串表示形式。该方法是String类中的方法
2.String转换为int
public static int parseInt(Strings):将字符串解析为int类型。该方法是Integer类中的方法

For example

package om.openlab.da14.packing;
public class InterDemo02 {

    public static void main(String[] args) {
        // int -> String
        int number = 100;
        // 方式1
        String s1 = number + "";
        System.out.println(s1);

        // 方式2
        // public static String valueOf(int i)
        String s2 = String.valueOf(number);
        System.out.println(s2);
        System.out.println("--------");

        // String -> int
        String s = "100";
        // 方式一
        // String -> Integer -> int
        Integer i = Integer.valueOf(s);
        // public int intValue()
        int x = i.intValue();
        System.out.println(x);
        // 方式2
        // public static int parseInt(String s)
        int y = Integer.parseInt(s);
        System.out.println(y);
    }
}

自动装箱和拆箱

装箱:把基本数据类型转换为对应的包装类类型

拆箱:把包装类类型转换为对应的基本数据类型

For example

package om.openlab.da14.packing;
public class IntegerDemo03 {
    public static void main(String[] args) {
        // 装箱,把基本数据类型转换为对应的包装类型
        Integer i = Integer.valueOf(100);
        Integer ii = 100; // Integer.valueOf(100)  自动装箱

        // 拆箱,把包装类类型转换为对应的基本数据类型
        // ii +=200;
//        ii = ii.intValue() + 200; // ii.intValue() 这个就是拆箱
        ii += 200; // 自动拆箱
        System.out.println(ii);

        Integer iii = null;
       if (iii != null) {
           iii += 300; // NullPointerException 空指针异常
       }
    }
}

注意:在使用包装类类型的时候,如果做操作,最好先判断是否为null

推荐:只要是对象,在使用前就必须进行不为null的判断

String类

String类在java.lang包下,所以使用的时候不需要导包

String类代表字符串,Java程序中的所有字符串文字(例如“abc”)都被实现为此类的实例也就是说,Java程序中所有的双引号字符串,都是String类的对象

字符串的特点
字符串对象只有在编译时没法确认结果才会创建新的对象

字符串不可变,它们的值在创建后不能被更改虽然String的值是不可变的,但是它们可以被共享
字符串效果上相当于字符数组(char[ ]),但是底层原理是字节数组( byte[ ])

JDK8及以前是字符数组,JDK9及以后是字节数组

String构造方法

方法名说明
public String( )创建一个空白字符串对象,不含有任何内容
public String(char[] chs)根据字符数组的内容,来创建字符串对象
public String(byte[ ] bys)根据字节数组的内容,来创建字符串对象
String s = “abc” ;直接赋值的方式创建字符串对象,内容就是abc

For example

package om.openlab.da14.packing;
public class StringDemo {
    public static void main(String[] args) {
    
        String s1 = new String();
        System.out.println("s1:"+s1);

        char[] chs = {'a','b','c'};
        String s2 = new String(chs);
        System.out.println("s2:"+s2);

        byte[] bys = {97,98,99};
        String s3 = new String(bys);
        System.out.println("s3:"+s3);

        String s4 = "abc";
        System.out.println("s4:"+s4);
    }
}

字符串比较

1.==

比较字符串的地址

2.eaual()

比较字符串的内容

For example

String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2);       // false
System.out.println(s1.equals(s2));  // true

字符串拼接问题:

在java,一定不要循环拼接字符串,因为会产生大量的废弃字符串(无法被gc回收,常驻内存)

StringBuilder:线程不安全(非线程安全的)
StringBuffer: 是线程安全的

字符串常量池

此处转自博客:深入理解Java String类

/**
 * 运行结果为true false
 */
String s1 = "AB";
String s2 = "AB";
String s3 = new String("AB");
System.out.println(s1 == s2);
System.out.println(s1 == s3);

在这里插入图片描述

java中的字符串,都保存在字符串常量池中,而且有且只有一份!!字符串是一种常量


面试题:java中的字符串常量池,JVM的什么地方?

JDK7之前,类似于字符串常量池等等常量数据都是存储方法区(Method Area),也被叫做永久代
JDK7开始去永久代,将字符串常量池等等常量数据存储到堆内里。
JDK8,元数据区(Metaspace),将1.6其他一些存储在方法区的数据,挪到了元数据区中,
字符串常量池并没有被挪回去
言外之意:java从jdk7,字符串常量池存储在heap中,jdk之前是存储在永久代中。

注意: 在编译时,已经确定的结果的字符串,不会创建对象,直接比较常量池中的值
在编译的时候,结果不确定,则会创建字符串对象

StringBuilder

String,StringBuffer与StringBuilder的区别参考博客:
String,StringBuffer与StringBuilder的区别

StringBuilder是一个可变的字符串类,我们可以把它看成是一个容器这里的可变指的是StringBuilder对象中的内容是可变的

String和StringBuilder的区别:
String:内容是不可变的
StringBuilder:内容是可变的

StringBuilder构造方法

方法名说明
public StringBuilder( )创建一个空白可变字符串对象,不含有任何内容
public StringBuilder(String str)根据字符串的内容,来创建可变字符串对象

For example

package om.openlab.da14.packing;

public class StringBuilderDemo {

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        System.out.println("sb:"+sb);
        System.out.println("sb.length():"+sb.length());

        StringBuilder sb2 = new StringBuilder("hello");
        System.out.println("sb2:"+sb2);
        System.out.println("sb2.length():"+sb2.length());
    }
}

StringBuilder的添加和反转方法

方法名说明
public StringBuilder append(任意类型)添加数据,并返回对象本身
public StringBuilder reverse( )返回相反的字符序列

StringBuilder和 String相互转换

1.StringBuilder转换为String
public String toString():通过toString()就可以实现把StringBuilder转换为String

2.String转换为StringBuilder
public StringBuilder(String s):通过构造方法就可以实现把String转换为StringBuilder

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值