从0开始回顾Java---系列五

简介: Integer1、Integer a= 127,Integer b = 127;Integer c= 128,Integer d = 128;相等吗?答案是a和b相等,c和d不相等。● 对于基本数据类型==比较的值● 对于引用数据类型==比较的是地址Integer a= 127这种赋值,是用到了Integer自动装箱的机制。自动装箱的时候会去缓存池里取Integer对象,没有取到才会创建新的对象。如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用缓存池中的Integer对象,超过范围 a1==b1的结果是false。publi

Integer

1、Integer a= 127,Integer b = 127;Integer c= 128,Integer d = 128;相等吗?

答案是a和b相等,c和d不相等。

  • 对于基本数据类型==比较的值
  • 对于引用数据类型==比较的是地址

Integer a= 127这种赋值,是用到了Integer自动装箱的机制自动装箱的时候会去缓存池里取Integer对象,没有取到才会创建新的对象。


如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用缓存池中的Integer对象,超过范围 a1==b1的结果是false。

public static void main(String[] args) {
        Integer a = 127;
        Integer b = 127;
        Integer b1 = new Integer(127);
        System.out.println(a == b); //true
        System.out.println(b==b1);  //false
        Integer c = 128;
        Integer d = 128;
        System.out.println(c == d);  //false
}

什么是Integer缓存?

因为根据实践发现大部分的数据操作都集中在值比较小的范围,因此 Integer 搞了个缓存池,默认范围是 -128 到 127,可以根据通过设置JVM-XX:AutoBoxCacheMax=来修改缓存的最大值,最小值改不了。


实现的原理是int 在自动装箱的时候会调用Integer.valueOf,进而用到了 IntegerCache

public static Integer valueof(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}


很简单,就是判断下值是否在缓存范围之内,如果是的话去 IntegerCache 中取,不是的话就创建一个新的Integer对象。

IntegerCache是一个静态内部类, 在静态块中会初始化好缓存值。

private static class IntegerCache {
     ……
     static {
            //创建Integer对象存储
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
         ……
     } 
 }

2、String转Integer的方法有哪些?

String转成Integer,主要有两个方法:

  1. 使用Integer类的静态方法parseInt()。该方法接受一个字符串参数,并返回该字符串表示的整数。例如:
String str = "123";
int i = Integer.parseInt(str);
  1. 使用Integer类的静态方法valueOf()。该方法接受一个字符串参数,并返回该字符串表示的整数的Integer包装类对象。例如:
String str = "123";
Integer i = Integer.valueOf(str);

不管哪一种,最终还是会调用Integer类内中的parseInt(String s, int radix)方法

核心代码:

public static int parseInt(String s, int radix)  throws NumberFormatException{
    int result = 0;
    //是否是负数
    boolean negative = false;
    //char字符数组下标和长度
    int i = 0, len = s.length();
    ……
    int digit;
    //判断字符长度是否大于0,否则抛出异常
    if (len > 0) {
        …… 
        while (i < len) {
            // Accumulating negatively avoids surprises near MAX_VALUE
            //返回指定基数中字符表示的数值。(此处是十进制数值)
            digit = Character.digit(s.charAt(i++),radix);
            //进制位乘以数值
            result *= radix;        
            result -= digit;
        }
    } 
    //根据上面得到的是否负数,返回相应的值
    return negative ? result : -result;
}

注意:

  • 该方法不能将空字符串转换为整数,否则会抛出NumberFormatException异常。
  • 该方法不能将非数字字符串转换为整数,否则会抛出NumberFormatException异常。


Object

1、Object 类有哪些方法?  

Object 类是一个特殊的类,是所有类的父类,也就是说所有类都可以调用它的方法。它主要提供了以下 11 个方法,大概可以分为六类:

对象比较:

  •  public native int hashCode()   :native方法,用于返回对象的哈希码,主要使用在哈希表中,比如JDK中的HashMap。
  • public boolean equals(Object obj)用于比较2个对象的内存地址是否相等,String类对该方法进行了重写用户比较字符串的值是否相等。

对象拷贝

  • protected native Object clone() throws CloneNotSupportedExceptionnaitive方法,用于创建并返回当前对象的一份拷贝。一般情况下,对于任何对象 x,表达式 x.clone() != x 为true,x.clone().getClass() == x.getClass() 为true。Object本身没有实现Cloneable接口,所以不重写clone方法并且进行调用的话会发生CloneNotSupportedException异常。

对象转字符串:

  • public String toString()返回类的名字@实例的哈希码的16进制的字符串。建议Object所有的子类都重写这个方法。

多线程调度:

  • public final native void notify():native方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个
  • public final native void notifyAll():native方法,并且不能重写。跟notify一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程
  • public final native void wait(long timeout) throws InterruptedException:native方法,并且不能重写。暂停线程的执行。注意:sleep方法没有释放锁,而wait方法释放了锁 。timeout是等待时间。
  • public final void wait(long timeout, int nanos) throws InterruptedException:多了nanos参数,这个参数表示额外时间(以毫微秒为单位,范围是 0-999999)。所以超时的时间还需要加上nanos毫秒。
  • public final void wait() throws InterruptedException:跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念

反射:

  • public final native Class getClass():native方法,用于返回当前运行时对象的Class对象,使用了final关键字修饰,故不允许子类重写

垃圾回收:

  • protected void finalize() throws Throwable通知垃圾收集器回收对象


异常处理

1、异常有哪些分类?

所有异常都是 Throwable 的子类,分为 Error 和 Exception。

  • Error是系统内部错误,比如虚拟机异常,是程序无法处理的。
  • Exception的子类为RuntimeException异常和RuntimeException以外的异常(例如IOException)。


因此异常主要分为Error,RuntimeException异常和RuntimeException以外的异常(错误、运行时异常和编译时异常)

常见异常:   NullPointerException、ClassNotFoundException、arrayindexoutofboundsexception、ClassCastException(类型强制转换)

2、异常的处理方式?

针对异常的处理主要有两种方式:

  1. 遇到异常不进行具体处理,而是继续抛给调用者 (throw,throws)
  • 抛出异常有三种形式,一是 throw,一个 throws,还有一种系统自动抛异常。
  • throws 用在方法上,后面跟的是异常类,可以跟多个;而 throw 用在方法内,后面跟的是异常对象。
  1. try catch 捕获异常
  • 在catch语句块中捕获发生的异常,并进行处理。
  • try-catch捕获异常的时候还可以选择加上finally语句块,finally语句块不管程序是否正常执行,最终它都会必然执行


3、三道经典异常处理代码题

题目1

public class TryDemo {
    public static void main(String[] args) {
        System.out.println(test());
    }
    public static int test() {
        try {
            return 1;
        } catch (Exception e) {
            return 2;
        } finally {
            System.out.print("3");
        }
    }
}

执行结果:31。

try、catch。finally 的基础用法在 return 前会先执行 finally 语句块所以是先输出 finally 里的 3,再输出 return 的 1。

题目2

public class TryDemo {
    public static void main(String[] args) {
        System.out.println(test1());
    }
    public static int test1() {
        try {
            return 2;
        } finally {
            return 3;
        }
    }
}

执行结果:3。

try 返回前先执行 finally,结果 finally 里不按套路出牌,直接 return 了,自然也就走不到 try 里面的 return 了。

题目3

public class TryDemo {
    public static void main(String[] args) {
        System.out.println(test1());
    }
    public static int test1() {
        int i = 0;
        try {
            i = 2;
            return i;
        } finally {
            i = 3;
        }
    }
}

执行结果:2。

大家可能会以为结果应该是 3,因为在 return 前会执行 finally,而 i 在 finally 中被修改为 3 了,那最终返回 i 不是应该为 3 吗?

但其实,在执行 finally 之前,JVM 会先将 i 的结果暂存起来,然后 finally 执行完毕后,会返回之前暂存的结果而不是返回 i,所以即使 i 已经被修改为 3,最终返回的还是之前暂存起来的结果 2。

相关文章
|
5天前
|
JSON Java 编译器
从0开始回顾Java---系列六
IO 1、Java中IO流分为几种? 流按照不同的特点,有很多种划分方式: • 按照流的流向分,可以分为输入流和输出流; • 按照操作单元划分,可以划分为字节流和字符流; • 按照流的角色划分为节点流和处理流。 Java Io流共涉及40多个类,看上去杂乱,其实都存在一定的关联, Java I0流的40多个类都是从如下4个抽象类基类中派生出来的。 • InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。 • OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。 IO流用到了什么设计模式? 装饰器模式 2、既
|
5天前
|
存储 安全 Java
从0开始回顾Java---系列七
引言 1、常见集合有哪些? Java集合类主要由两个根接口Collection和Map派生出来的,Collection派生出了三个子接口:List、Set、Queue,因此Java集合大致也可分成List、Set、Queue、Map四种接口体系。 ● List代表了有序可重复集合,可直接根据元素的索引来访问; ● Set代表无序不可重复集合,只能根据元素本身来访问; ● Queue是队列集合。 ● Map代表的是存储key-value对的集合,可根据元素的key来访问value。 2、线程安全的集合有哪些?线程不安全的呢? 线程安全的: ● Hashtable:比HashMap多了个线
|
5天前
|
存储 安全 Java
从0开始回顾Java---系列三
面向对象 1、谈一谈你对面向对象的理解 ? 面向过程: 一件事该怎么做,注重实现过程,以过程为中心; 面向对象: 实现对象是谁,只关心怎样使用,不关心具体实现(只关心实现对象是谁,有封装、继承、多态三大特性); 总结: ● 面向对象是一种编程思想,早期的面向过程的思想就是一件事该怎么做,而面向对象就是一件事该由谁来做,它怎么做的我不管,我只需要调用就行。而这些是由面向对象的三大特性来实现的,三大特性就是封装、继承、多态。 2、面向对象的三大特性? 封装:封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法。 多态: 所谓多态就是指程序中定义的引用变量所指
|
5天前
|
存储 缓存 安全
从0开始回顾Java---系列四
String 1、String 是 Java 基本数据类型吗?可以被继承吗?为什么? String是Java基本数据类型吗? 不是。Java 中的基本数据类型只有8个:byte、short、int、long、float、double、char、boolean;除了基本类型(primitive type),剩下的都是引用类型(reference type)。 String是一个比较特殊的引用数据类型。 String 类可以继承吗? 不行。String 类使用 final 修饰,是所谓的不可变类,无法被继承。 String 类为什么要被设计成不可继承? 1. 字符串是一种非常重要且常用的数据类型
|
5天前
|
存储 安全 算法
从0开始回顾Java---系列八
HashMap 1、HashMap 有什么特点? HashMap 基于哈希表的 Map 接口实现,是以 key-value 存储形式存在,主要用来存放键值对。 特点: ● HashMap 的实现不是同步的,这意味着它不是线程安全的 ● key 是唯一不重复的,底层的哈希表结构,依赖 hashCode 方法和 equals 方法保证键的唯一 ● key、value 都可以为null,但是 key 位置只能是一个null ● HashMap 中的映射不是有序的,即存取是无序的 ● key 要存储的是自定义对象,需要重写 hashCode 和 equals 方法,防止出现地址不同内
|
5天前
|
存储 安全 算法
从0开始回顾Java---系列九
TreeMap 1、TreeMap 有什么特点? 1. TreeMap是基于红黑树的一种提供顺序访问的Map,增删改查的平均和最差时间复杂度均为 O(logn) ,最大特点是 Key 有序。 2. Key 必须实现 Comparable 接口或提供的 Comparator 比较器,所以 Key 不允许为 null。 3. TreeMap是一个线程不安全,有序的键值对集合,因为TreeMap实现了SotredMap接口。 4. TreeMap实现了Cloneable接口,可被克隆,实现了Serializable接口,可序列化; 2、讲讲 TreeMap 怎么实现有序的? TreeMap
|
Java 编译器
强哥说Java--Java基础
强哥说Java--Java基础
61 0
|
存储 Java 开发者
[Java --- List]
我们之前实现过的顺序表,只能保存 int 类型的元素,如果现在需要保存 指向 Person 类型对象的引用的顺序表,请问应该如何解决?如果又需要保存指向 Book 对象类型的引用呢?
|
Java
Java报错:Cause: java.io.NotSerializableException: xxx 解决方案
原因是实体类没有开启序列化接口导致的 开启实体类序列化接口即可:
110 0
|
Java 编译器
Java---继承
继承的基本思想是,基于已有的类创造新的类。继承已存在的类就是复用这些类的方法,而且可以增加一些新的方法和字段,使新类能够适应新的情况,继承是Java程序设计中一项核心技术,它主要解决的问题是:共性的抽取,实现代码复用。
Java---继承