Java中的三大特殊类

今天来总结一下Java中的三大特殊类:String类, Object类, 和包装类
一,String类

1. String类的两种实例化方式
★ 直接赋值 :

String str = "Hello World" ; // str是一个对象,那么"Hello World" 就应该保存在堆内存中 
System.out.println(str) ;

★ 传统方法(构造法):

String str = new String("Hello Bit") ; 
System.out.println(str) ;

● 两种实例化的区别:
1).采用直接赋值:

 String str1 = "hello" ;  
 String str2 = "hello" ;  
 String str3 = "hello" ;  
 System.out.println(str1 == str2); // true   
 System.out.println(str1 == str3); // true    
 System.out.println(str2 == str3); // true

采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中。如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用;如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用。
所谓的对象池就是一个对象数组(目的就是减少开销)

2).采用构造方法

String str = new String("hello") ;

如果使用String构造方法,则在程序编译期会先去字符串常量池检查,是否存在“hello”,如果不存在则开辟一块空间存放“hello”,存在的话就不会开辟,然后在堆内存中开辟一块空间来存放new出来的String实力,再在战中开辟一块空间命名为str,存放堆内存中String实例的地址。
在String类中提供有方法入池操作 public String intern() ;

// 该字符串常量并没有保存在对象池之中    
   String str1 = new String("hello") ;       
   String str2 = "hello" ;       
   System.out.println(str1 == str2); // false
//方法入池后   
   String str1 = new String("hello").intern() ;  
   String str2 = "hello" ;        
   System.out.println(str1 == str2); // true

总结:
String类中两种对象实例化的区别 :
1). 直接赋值:只会开辟一块堆内存空间,并且该字符串对象可以自动保存在对象池中以供下次使用。
2). 构造方法:会开辟两块堆内存空间,其中一块成为垃圾空间,不会自动保存在对象池中,可以使用 intern()方法手工入池。

因此,我们一般会采取第一种方式即直接赋值
String类的其中一种构造方法如下: public String(String str) ;

2, 字符串相等比较

观察以下代码的输出

int x = 10 ;
int y = 10 ;
System.out.println(x==y); //true
String str1 = "Hello" ;
String str = new String("Hello") ;
System.out.println(str1==str); // false 

为什么两个字符串内容相同,而使用 == 得到的结果不同。
来看内存图分析:
在这里插入图片描述可知:== 本身是进行数值比较的,若用于对象比较,则比较的是两个对象所保存的内存地址是否相等,而并没有比较对象的内容。
若想要进行内容比较,则必须采用String类提供的equals方法:

 String str1 = "Hello" ;
 String str = new String("Hello") ;
 System.out.println(str1.equals(str));

由此可知:
==比较与equals比较的区别是:
(1) ==:进行数值比较,比较的是两个字符串对象的内存地址数值。
(2) “equals()”:可以进行字符串内容的比较

3,字符串不可变更

字符串一旦定义不可改变。
判断如下代码共开辟了多少块内存空间:

 String str = "hello" ;  
 str = str + " world" ;   
 str += "!!!" ;   
 System.out.println(str); // hello world!!!

一起来看看这段代码内存模型:
在这里插入图片描述可以发现字符串上没有发生任何变化,但是字符串对象的引用一直在改变,而且会形成大量的垃圾空间。因此我们应该尽量避免在代码中用循环对字符变量的引用不断赋值。
关于字符串的一些方法:

方法名称类型描述
public boolean equals(Object anobject)普通区分大小写的比较
public boolean equalsIgnoreCase(String anotherString)普通不区分大小写的比较
public int compareTo(String anotherString)普通比较两个字符串大小关系
public boolean contains(CharSequence s)普通判断一个子字符串是否存在
public int indexOf(String str)普通从头开始查找指定字符串的位置,查到了返回位置的开始索引,查不到返回-1
public int indexOf(String str,int fromIndex)普通从指定位置开始查找子字符串位置
public int LastIndexof(String str)普通由后向前查找子字符串位置
public int LastIndexof(String str,int fromIndex)普通从指定位置由后向前查找
public boolean startsWith(String prefix)普通判断是否由指定字符串开头
public boolean startsWith(String prefix,int toffset)普通从指定位置开始判断是否以指定字符串开头
public boolean endsWith(String suffix)普通判断是否以指定字符串结尾
public String(byte bytes[])构造将字节数组变为字符串
public String(byte bytes[],int offset,int Length)构造将部分字节数组中的内容变为字符串
public byte[] getBytes()普通将字符串以字节数组的形式返回
public String(char value[])构造将字符数组中的所有内容变为字符串
public String(char value[],int offset,int count)构造将部分字符数组中的内容变为字符串
public char charAt(int index)普通取得指定索引位置的字符,索引从0开始
public char[] toCharArray()普通将字符串变为字符数组返回
public String replaceAll(String regex,String replacement)普通替换所有指定内容
public String replaceFirst(String regex,String replacement)普通替换首个内容
public String[] split(String regex)普通将字符串全部拆分
public String[] split(String regex,int limit)普通将字符串部分拆分,该数组长度就是limit极限
public String substring(int beginIndex)普通从指定索引截取到结尾
public String substring(int beginIndex,int endIndex)普通截取部分内容
public String trim()普通去掉字符串中的左右空格,保留中间空格
public String toUpperCase()普通字符串转大写
public String toLowerCase()普通字符串转小写
public native String intern()普通字符串入池操作
public String concat(String str)普通字符串连接,等同于“+”,不入池
public int Length()普通取得字符串长度
public boolean isEmpty()普通判断是否为空字符串,但不是null,而是长度为0

4, StringBuffer类
String类的特点:任何的字符串常量都是String对象,而且String的常量一旦声明不可改变,如果改变对象内容,改变的是其引用的指向而已。
由于String的不可更改特性,为了方便字符串的修改,提供StringBuffer类。 在String中使用"+"来进行字符串连接,但在StringBuffer类中需要更改为append()方法:

public synchronized StringBuffer append(各种数据类型 b)

来看看StringBuffer的使用:

public class Stringbuffer {

        public static void main(String[] args) {
            StringBuffer sb = new StringBuffer();
            sb.append("Hello").append("World");
            fun(sb);
            System.out.println(sb);
        }    
        public static void fun(StringBuffer temp) {
            temp.append("\n").append("welcome to china");
        }
}

输出结果如下:

"C:\Program Files\Java\jdk1.8.0_131\bin\java" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1\lib\idea_rt.jar=28563:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;D:\code\java\Base\target\classes" String.Stringbuffer
HelloWorld
welcome to china

Process finished with exit code 0

String和StringBuffer大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串 的情况考虑使用StingBuffer。
两个类都是"CharSequence"接口的子类。
注意:String和StringBuffer类不能直接转换。
如果要想互相转换,可以采用如下原则:
●String变为StringBuffer:利用StringBuffer的构造方法或append()方法
● StringBuffer变为String:调用toString()方法。
除了append()方法外,StringBuffer也有一些String类没有的方法:
★字符串反转:

public synchronized StringBuffer reverse()

★删除指定范围的数据:

public synchronized StringBuffer delete(int start, int end)

★插入数据:

public synchronized StringBuffer insert(int offset, 各种数据类型 b)

二,Object类
Java里面除了Object类,所有的类都是存在继承关系的。默认会继承Object父 类。即,所有类的对象都可以使用Object进行接收。

方法名称类型描述
public Object()构造取得无参构造为子类服务
public String toString()普通取得对象信息
public boolean equals(Object obj)普通进行对相比较

在使用对象直接输出的时候,默认输出的是一个地址编码。如果现在使用的是String类,该类对象直接输出的是内容,主要原因就是toString()方法的问题。默认Object类提供的toString()方法只能够得到一个对象的地址(而这是所有对象都共同具备 的特征)。
toString()的核心目的在于取得对象信息。 String作为信息输出的重要数据类型,在Java中所有的数据类型只要遇见了String并且执行了 + ,那么都要求将其变 为字符串后连接,而所有对象要想变为字符串就默认使用 toString() 方法。
2. 对象比较
String类对象的比较使用的是equals()方法,实际上String类的equals()方法就是覆写的Object类中的equals()方法。
3. 接收引用数据类型
现在知道Object可以接收任意的对象,因为Object是所有类的父类,但是Obejct并不局限于此,它可以接收所有数据类型,包括:类、数组、接口。Object可以接收接口是Java中的强制要求,因为接口本身不能继承任何类。
来看一个Object类接受接口的例子:

interface IMessage {  
  public void getMessage() ;
 } 
   
 class MessageImpl implements IMessage {  
 
    @Override  
     public String toString() {   
            return "I am small girl" ;  
     }   
     public void getMessage() {    
            System.out.println("中国欢迎你");   
         } 
} 

public class Test {   
    public static void main(String[] args) {    
           IMessage msg  = new MessageImpl() ; // 子类向父接口转型     
           Object obj = msg ; // 接口向Obejct转型   
           System.out.println(obj);     
           IMessage tem = (IMessage) obj ; // 强制类型转换  
           temp.getMessage();  
      }
  }

Object真正达到了参数的统一,如果一个类希望接收所有的数据类型,就是用Object完成。
三 ,包装类
在Java中,数据类型分为基本数据类型和引用数据类型,Object类可以接收所有引用数据类型。那么基本数据类型如何处理呢?
1, 基本原理
包装类就是将基本数据类型封装到类中。
利用IntValue就可以实现基本数据类型变为对象的需求。将基本数据类型包装为一个类对象的本质就是使用Object进行接收处理。

●数值型(Number的子类):Byte,Short,Integer(int),Long,Float,Double
● 对象型(Object的子类):Boolean,Character(char)

2, 装箱与拆箱
在包装类与基本数据类型处理之中存在有两个概念:
●装箱:将基本数据类型变为包装类对象,通过每个包装类的构造方法实现装箱处理。
●拆箱:将包装类中包装的基本数据类型取出,利用包装类提供的XxValue()方法。
例如:

public class Test {
    public static void main(String[] args){
        //装箱
        Integer integer=new Integer(10);
        //拆箱
        int data=integer.intValue();
        System.out.println(data+10);
    }
}

Java在JDK1.5之后就提供了自动拆装箱机制,使用包装类与使用基本类型在用法上基本一致。
使用基本类还是包装类?
1)【强制】所有POJO类(类中只有属性与getter/setter,构造方法)使用包装类。
2)局部变量推荐使用基本类。包装类进行数值比较使用equals方法。
对于 Integer var = ? 在-128 至 127 范围内的赋值,Integer 对象是在IntegerCache.cache 产生,会复用 已有对象,这个区间内的 Integer 值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产 生,并不会复用已有对象,这是一个大坑,推荐使用 equals 方法进行判断。

3. 字符串与基本数据类型转换

如何将字符串变为各个数据类型,这个时候就需要包装类支持。
字符串---->基本数据类型
★ String变为int 类型(Integer类):public static int parseInt(String s) throws NumberFormatException
★ String变为double类型(Double类):public static double parseDouble(String s) throws NumberFormatException
★ String变为Boolean类型(Boolean类):public static boolean parseBoolean(String s)
eg:将字符串变为int 型

String str = "123" ; // String类型
 int num = Integer.parseInt(str) ; 
 System.out.println(num);

注意:将字符串转为数字的时候,字符串的组成有非数字,那么转换就会出现错误 (NumberFormatException)
基本数据类型---->字符串:
★任何数据类型使用了"+"连接空白字符串就变为了字符串类型。
★使用String类中提供的valueOf()方法,此方法不产生垃圾。
eg:

 String str = String.valueOf(100) ;  
 System.out.println(str);
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
1 Java程序源代码须先通过 编译器 产生Java虚拟机器的机器码 bytecode 再经过解释器将其转成实际使用的机器和操作系统上的机器码执行 2 定义有 abstract 方法 此一定要声明为抽象 3 在java语言定义 所有的都可以视作是 Object 的子 4 创建动画是java的重要功能之一 但经常出现闪烁 解决闪烁现象可用 重写update 和 图形双缓冲 方法 5 java程序分为 application 和applet两种 java applet的生命周期的start方法在 执行完init方法后 以及从其他网页再回到这个applet 时候执行 java applet的生命周期的stop方法在 离开applet的网页时执行 时候执行 java applet的生命周期的四个主要方法 init start stop destroy 6 7 java图形不但提供了一些绘图方法 还可以装载 jpeg 和 gif 两种格式的图形文件 在APPLET程序显示一图片文件需用到 getImage 和 drawImage 方法 8 java 例外可以分为三大: Error Exception RuntimeException Java允许 Exception 例外不被catch 且在throw它们时 也不需要声明在方法原型声明的throws子句 9 Thread最重要的方法是 start 和 run 10 OutputStream的功能是 接受要输出的字节并将它送往目的地 InputStream的功能是 输入字节流 11 针对网络通信的不同层次 Java提供的网络功能有四大:InetAddress URL Socket DatagramSocket ">1 Java程序源代码须先通过 编译器 产生Java虚拟机器的机器码 bytecode 再经过解释器将其转成实际使用的机器和操作系统上的机器码执行 2 定义有 abstract 方法 此一定要声明为抽象 [更多]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值