java -- Object类和String类

Posted _泡泡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java -- Object类和String类相关的知识,希望对你有一定的参考价值。

Object类

java.lang.Object类是Java语言中的根类,每个类都使用 Object 作为超类, 所有的类都直接或间接继承自 Object 类。所有对象(包括数组)都实现这个类的方法。

native 本地方法

在Object类的源码中定义了native修饰的方法,native修饰的方法称为本地方法。

特点

  • 被native修饰的方法,非Java语言编写,是由C++语言编写。
  • 本地方法在运行时期进入本地方法栈内存,本地方法栈是一块独立内存的区域。
  • 本地方法的意义是和操作系统进行交互。
private static native void registerNatives();
static 
    registerNatives();

当程序运行的时候,Object类会最先被加载到内存中。类进入内存后首先加载自己的静态成员,static代码块中调用了本地方法registerNatives(),和操作系统进行交互。

toString方法

方法声明:public String toString():返回该对象的字符串表示。
Object类toString()方法源码:

public String toString() 
	return getClass().getName() + "@" + Integer.toHexString(hashCode());

源码分析:

  • getClass().getName()返回类的全限定名字。
  • hashCode()方法返回int值,可以暂时理解为对象的内存地址。
  • Integer.toHexString()将int类型的值转成十六进制。
  • 因此调用对象的toString()方法将看到内存的地址值。

创建Person类,并调用方法toString()

public static void main(String[] args)
    Person person = new Person();
    String str = person.toString();
    System.out.println(str);
    System.out.println(person);

通过程序运行,得到结论,在输出语句中打印对象,就是在调用对象的toString()方法

重写toString方法

由于toString方法返回的结果是内存地址,而在开发中,内存地址并没有实际的应用价值,经常需要按照对象的属性得到相应的字符串表现形式,因此也需要重写它。

public class Person   
    private String name;
    private int age;

    @Override
    public String toString() 
        return "Person"+name+":"+age;
    
    // 省略构造器与Getter Setter

equals方法

方法声明:public boolean equals(Object obj):指示其他某个对象是否与此对象“相等”。

Object类equals()方法源码:

public boolean equals(Object obj) 
    return (this == obj);

源码分析:

  • this是当前对象,哪个对象调用的equals方法就表示哪个对象。
  • obj表述传递的参数,参数类型Object,可以传递任意类型对象。
  • this==obj 比较两个对象的内存地址是否相同

equals方法默认比较两个对象的内存地址是否相同,相同则返回true。

重写equals方法

实际应用中,比较内存地址是否相同并没有意义,我们可以定义对象自己的比较方式,比较对象中成员变量的值是否相同。需要对方法进行重写。

需求:重写equals()方法,比较两个对象中姓名和年龄是否相同,如果姓名和年龄都相同返回true,否则返回false。

public class Person 
    private String name;
    private int age;
    
    public boolean equals(Object obj)
        //判断两个对象地址弱相同,即为同一个对象
        if(this == obj)
            return true;
        //obj对象为空,无需比较,返回false
        if(obj == null)
            return  false;
        //obj如果是Person类型对象,则强制转换
        if(obj instanceof Person)
            Person person = (Person)obj;
            //比较两个对象的name属性和age属性,如果相等,返回true
            return this.name.equals(person.name) && this.age == person.age;
        
        return false;
    

hashCode方法

方法声明 public native int hashCode();
返回一个哈希值

哈希值: 可以理解为一个唯一值 或 逻辑地址

调用hashCode, 比较两对象的哈希, 相当于比较两个对象的地址值
重写hashCode, 比较两对象的内容
若想确定内容是否真的相同 先比较两对象的hashCode(因为比较数字较容易)

  • 不同 说明两对象内容一定不同
  • 相同 不能说明两对象一定相同 需要继续比较 equals, 比较其内容

重写hashCode方法

public int hashCode() 
	// 成员变量是引用类型, 直接调用hashCode方法得到一个int值
	// 成员变量是基本类型, 直接使用对应的值
	int result = name != null ? name.hashCode() : 0;
	result = 31 * result + age;
	return result;

String类

java.lang.String 类代表字符串。Java程序中所有的字符串文字(例如"abc" )都可以被看作是实现此类的实例。

特点

1.字符串不变:字符串的值在创建后不能被更改。

String s1 = "abc";
s1 += "d";
System.out.println(s1); // "abcd" 
// 内存中有"abc","abcd"两个对象,s1从指向"abc",改变指向,指向了"abcd"。

2.因为String对象是不可变的,所以它们可以被共享。

String s1 = "abc";
String s2 = "abc";
// 内存中只有一个"abc"对象被创建,同时被s1和s2共享。

3."abc" 等效于 char[] data= \'a\' , \'b\' , \'c\' ,但是底层原理是字节数组( byte[] )

例如:
String str = "abc";
相当于: 
char data[] = \'a\', \'b\', \'c\';     
String str = new String(data);
// String底层是靠字符数组实现的。

构造方法

  • public String() :初始化新创建的 String对象,以使其表示空字符序列。

  • public String(char[] value) :通过当前参数中的字符数组来构造新的String。

  • public String(byte[] bytes) :通过使用平台的默认字符集解码当前参数中的字节数组来构造新的String。

  • 直接赋值的方式创建字符串对象

构造举例,代码如下:

public class StringDemo01 
    public static void main(String[] args) 
        //public String():创建一个空白字符串对象,不含有任何内容
        String s1 = new String();
        System.out.println("s1:" + s1);

        //public String(char[] chs):根据字符数组的内容,来创建字符串对象
        char[] chs = \'a\', \'b\', \'c\';
        String s2 = new String(chs);
        System.out.println("s2:" + s2);

        //public String(byte[] bys):根据字节数组的内容,来创建字符串对象
        byte[] bys = 97, 98, 99;
        String s3 = new String(bys);
        System.out.println("s3:" + s3);

        //String s = “abc”;	直接赋值的方式创建字符串对象,内容就是abc
        String s4 = "abc";
        System.out.println("s4:" + s4);
    

常用方法

获取字符串的长度

public int length () : 返回此字符串的长度

字符串拼接

public String concat (String str) :将指定的字符串连接到该字符串的末尾。

String s12 = "abc".concat("bcd");
System.out.println("concat拼接后: " + s12);

字符串 转换为 字符数组

public char[] toCharArray()

char[] strToChar =  s4.toCharArray();
for (int i = 0; i < strToChar.length; i++) 
	System.out.print(strToChar[i] + " ");

System.out.println();

字符串 转换为 字节数组

public byte[] getBytes()

byte[] strToByte = s2.getBytes();
for (int i = 0; i < strToByte.length; i++) 
	System.out.print(strToByte[i] + " ");

获取指定索引位置的元素

public char charAt (int index) :返回指定索引处的 char值。

// 根据索引找字符, 若索引不存在, 抛出StringIndexOutOfBoundsException(字符串索引越界异常)
String s = "I Love Java";
char c = s.charAt(0);
System.out.println(c);
for (int i = 0; i < s.length(); i++) 
	System.out.print(s.charAt(i));

System.out.println();

获取指定字符索引

public int indexOf (String str) :返回指定子字符串第一次出现在该字符串内的索引。
int indexOf(String str, int fromIndex): 从指定索引位置开始查找
lastIndexOf(String str): 查找字符(串)最后一次出现的位置的索引

参数可以是char, int 或 String 类型

int index = s.indexOf(\'a\');
System.out.println("字符a第一次出现的索引位置: " + index);
System.out.println("97对应的字符第一次出现的位置: " + s.indexOf(97) );
// 字符a第二次出现的索引位置
System.out.println("字符a第二次出现的索引位置: " + s.indexOf(\'a\', index + 1) );

s1 = "abcaaaabcaab";
int abIndex = s1.indexOf("ab");
System.out.println("字符串ab第一次出现的索引位置: " + abIndex);
int abIndex2 = s1.indexOf("ab", abIndex + 1);
// int abIndex2 = s1.indexOf("ab", abIndex + "ab".length());
System.out.println("字符串ab第二次出现的索引位置: " + abIndex2);
System.out.println("字符串ab第三次出现的索引位置: " + s1.indexOf("ab", abIndex2 + 1));

String path = "d:\\\\work\\\\abc\\\\1.txt";
// 查询字符\'\\\'最后一次出现的位置
System.out.println(path.lastIndexOf(\'\\\\\'));

字符串截取

substring(int startIndex): 从开始索引截取到末尾
substring(int startIndex, int endIndex): 截取字符串中 [start, end)的字符串

因为字符串不可改变, 所以返回一个新的字符串

// 截取Love
String subLove = s.substring(2, 6);
System.out.println(subLove);
// 截取文件名
int lastIndex = path.lastIndexOf(\'\\\\\');
String fileName = path.substring(lastIndex + 1);
System.out.println(fileName);

去除字符串两端空格

public String trim()

String s13 = "             ab       c      ";
System.out.println("原字符串: " + s13);
System.out.println("去除两端空格: " + s13.trim());

字符串替换

public String replace (CharSequence target, CharSequence replacement) : 将与target匹配的字符串使用replacement字符串替换
public String replaceAll(String regex, String replacement): 将与regex(正则)匹配的字符串使用replacement字符串替换
区别: replaceAll支持正则表达式, 而replace不支持

String s14 = "张三-李四-王五-赵六";
String s15 = s14.replace("-", " ");
System.out.println("replace替换: " + s15);
s14 = "张三--------李四---王五--赵六";
String s16 = s14.replaceAll("-+", " ");
System.out.println("replaceAll替换: " + s16);

切割字符串

public String[] split(String regex) :将此字符串按照给定的regex(正则)拆分为字符串数组

String[] strArr = s14.split("-+");
for (String s : strArr) 
	System.out.print(s + " ");

System.out.println();
// 以\'.\'分割ip地址
String myIp = "192.168.1.1";
// \'.\'在正则中表示匹配任意字符, \'\\\'为转义符, java要拿到\'\\\', 需要对\'\\\'转义, 即\'\\\\\'
strArr = myIp.split("\\\\.");
for (String s: strArr) 
	System.out.print(s + " ");

System.out.println();

Java基础—API及Object类和String类

Java APIAPI: Application(应用) Programming(程序) Interface(接口)

Java API就是JDK中提供给我们使用的类,这些类将底层的代码实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可。

1.Object类

 Object类是Java语言中的根类,即所有类的父类。它中描述的所有方法子类都可以使用。所有类在创建对象的时候,最终找的父类就是Object

  equals方法

   equals方法,用于比较两个对象是否相同,它其实就是使用两个对象的内存地址在比较。Object类中的equals方法内部使用的就是==比较运算符。

  

在开发中要比较两个对象是否相同,经常会根据对象中的属性值进行比较,也就是在开发经常需要子类重写equals方法根据对象的属性值进行比较。

如下代码演示:

 

/*

 

  描述人这个类,并定义功能根据年龄判断是否是同龄人

 

  由于要根据指定类的属性进行比较,这时只要覆盖Object中的equals方法

 

  在方法体中根据类的属性值进行比较

 

 */

 

class Person extends Object

 

int age ;

 

//复写父类的equals方法,实现自己的比较方式

 

public boolean equals(Object obj)

 

//判断当前调用equals方法的对象和传递进来的对象是否是同一个

 

if(this == obj)

 

return true;

 

 

//判断传递进来的对象是否是Person类型

 

if(!(obj instanceof Person))

 

return false;

 

 

//obj向下转型为Perosn引用,访问其属性

 

Person p = (Person)obj;

 

return this.age == p.age;

 

 

 

注意:在复写Object中的equals方法时,一定要注意public boolean equals(Object obj)的参数是Object类型,在调用对象的属性时,一定要进行类型转换,在转换之前必须进行类型判断。

 

 

 toString方法

toString方法返回该对象的字符串表示,其实该字符串内容就是对象的类型+@+内存地址值。

 

由于toString方法返回的结果是内存地址,而在开发中,经常需要按照对象的属性得到相应的字符串表现形式,因此也需要重写它。

 

class Person extends Object

 

int age ;

 

//根据Person类的属性重写toString方法

 

public String toString()

 

return "Person [age=" + age + "]";

 

 

 

 

2.String类

String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。

 

//演示字符串:

 

String str  = "oracle";

 

str = "甲骨文";

字符串的本质是一个字符的数组。

代码演示:

String s3 = "abc";

 

String s4 = new String("abc");

 

System.out.println(s3==s4);//false

 

System.out.println(s3.equals(s4));//true,

 

//因为String重写了equals方法,建立了字符串自己的判断相同的依据(通过字符串对象中的字符来判断)

 

 

 

s3和s4的创建方式有什么不同呢?

 

s3创建,在内存中只有一个对象。这个对象在字符串常量池中

 

 s4创建,在内存中有两个对象。一个new的对象在堆中,一个字符串本身对象,在字符串常量池中

 

 

String构造方法

 

  

String s1 = new String(); //创建String对象,字符串中没有内容

 

byte[] bys = new byte[]97,98,99,100;

String s2 = new String(bys); // 创建String对象,把数组元素作为字符串的内容

String s3 = new String(bys, 1, 3); //创建String对象,把一部分数组元素作为字符串的内容,参数offset为数组元素的起始索引位置,参数length为要几个元素

 

char[] chs = new char[]’a’,’b’,’c’,’d’,’e’;

String s4 = new String(chs); //创建String对象,把数组元素作为字符串的内容

String s5 = new String(chs, 0, 3);//创建String对象,把一部分数组元素作为字符串的内容,参数offset为数组元素的起始索引位置,参数count为要几个元素

 

String s6 = new String(“abc”); //创建String对象,字符串内容为abc

 

 

 

字符串是一个对象,那么它的方法必然是围绕操作这个对象的数据而定义的

字符串的功能:

1)返回此字符串的长度(length()/int)

String str = "abcde";

 

int len = str.length();

 

System.out.println("len="+len);

 

 

2)获取部分字符串(substring()/String)

String str = "abcde";

 

String s1 = str.substring(1); //返回一个新字符串,内容为指定位置开始到字符串末尾的所有字符

 

String s2 = str.substring(2, 4);//返回一个新字符串,内容为指定位置开始到指定位置结束所有字符

 

System.out.println("str="+str);

 

System.out.println("s1="+s1);

 

System.out.println("s2="+s2);

 

3)测试此字符串是否以指定字符串开头和结尾(startsWith(),endWith() / boolean)

String str = "StringDemo.java";

boolean b1 = str.startsWith("Demo");//判断是否以给定字符串开头

boolean b2 = str.startsWith("String");

boolean b3 = str.endsWith("java");//判断是否以给定字符串结尾

 

4)判断此字符串是否包含指定字符串(contains()/boolean)

String str = "abcde";

boolean b2 = str.contains("bcd");//判断是否包含指定字符串,包含返回true,不包含返回false

 

5)返回第一次出现该字符串的索引,不包含则返回-1(indexOf () / int )

String str = "abcde";int index = str.indexOf(“bcd”); //判断是否包含指定字符串,包含则返回第一次出现该字符串的索引,不包含则返回-1

 

6)将字符串转化成一个字节数组(getBytes() / byte[])

 

String str = "abcde";

byte[] bytes = str.getBytes();

 

7)将字符串转化成一个字符数组(toCharArray() / char[])

String str = "abcde";

char[] chs = str.toCharArray();

 

8)判断两个字符串的内容是否相同(equals()/ boolean)equalsIgnoreCase() 不区分大小写

String str = "abcde";

String str2 = "abcde";

String str3 = "hello";

boolean b1 = str.equals(str2);

boolean b2 = str.equals(str3);

 

 

StringBuffer类

  API中说字符串缓冲区支持可变的字符串

 

 StringBuffer是个字符串的缓冲区,即就是它是一个容器,容器中可以装很多字符串。并且能够对其中的字符串进行各种操作。

 StringBuffer一些功能代码演示:(可查阅API进行学习)

创建一个字符串缓冲区对象。用于存储数据。

 

StringBuffer sb = new StringBuffer();

 

sb.append("haha"); //添加字符串

 

sb.insert(2, "it");//在指定位置插入

 

sb.delete(1, 4);//删除

 

sb.replace(1, 4, "cast");//替换指定范围内的内容

 

String str = sb.toString();

 

在我们开发中,会遇到调用一个方法后,返回一个对象的情况。然后使用返回的对象继续调用方法。这种时候,我们就可以把代码现在一起,如append方法一样,代码如下:

创建一个字符串缓冲区对象。用于存储数据。

StringBuffer sb = new StringBuffer();

添加数据。不断的添加数据后,要对缓冲区的最后的数据进行操作,必须转成字符串才可以。

String str = sb.append(true).append("hehe").toString();

 

 

 

StringBuilder

  它也是一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。

 

 

 

 

 

 

 

 

 

以上是关于java -- Object类和String类的主要内容,如果未能解决你的问题,请参考以下文章

Object类 包装类和数学处理类 String类

Object类和String类equals方法有什么区别?

JAVA面向对象的多态性及抽象类和接口

Java全栈JavaSE:17.常用类之Object类String类StringBuilder类

深入研究java.lang.Object类

Java中的集合和常用类