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 的API(API: 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类的主要内容,如果未能解决你的问题,请参考以下文章