Java基础记录

mac2024-12-02  21

Java基础

Int 和 Inetger

今天参见了一场电话面试其中被问到了Int 和Inetger 的区别,当时也就只谈:1.包装类型和原始数据类型,2.自动装箱和自动拆箱,也不知道知否全面。

之后还是需要将他们总结一下:

首先,int是我们常说的整形数字,是Java的8个原始数据类型(boolean、byte 、short、char、int、foat、double、long)之一。Java语言虽然号称一切都是对象,但原始数据类型是例外。

原始数据类型

那么原始数据类型又是什么呢?故事其实这样的在Java设计之初,它保留了一些和面向过程语言的特性(如:C),原始数据类型不是对象,没有方法,但是可以简单快速处理数据。 原始数据类型分类 :

整型:byte、short、int、long浮点型:float、double布尔型:boolean字符:char

各种数据类型取值范围如下:

数据类型字节取值范围byte1-2^-7 ~ 2^7-1(-128 ~ 127)short2-2^-15 ~ 2^15-1int4-2^31 ~ 2^31-1long8-2^63 ~ 2^63-1float4大约±3.402 823 47E+38F(6~7位有效数字)double8大约±1.797 693 134 862 315 70E+308(15位有效数字)

取值范围与字节数相关 1 b= 8 位,在记录时 有一个字节用来记录符号所以对于 byte来说他的取值范围位 -2^-7 ~ 2^7-1(-128 ~ 127) 其他基本型也是同样的道理。

其中

char类型:

表示单个字符,他的值需要用 ‘ ’括起来,如 ‘A’

boolean类型

它只有两个值 true 和 false;

包装类型

在Java 5中,引入了自动装箱和自动拆箱功能(boxing/unboxing),Java可以根据上下文,自动进行转换,极大地简化了相关编程。

关于Integer的值缓存,这涉及Java 5中另一个改进。构建Integer对象的传统方式是直接调用构造器,直接new一个对象。但是根据实践,我们发现大部分数据操作都是集中在有 限的、较小的数值范围,因而,在Java 5中新增了静态工厂方法valueOf,在调用它的时候会利用一个缓存机制,带来了明显的性能改进。按照Javadoc,这个值默认缓存是-128到127之间。

关于Integer中的缓存机制,废话不多先上代码

private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }

从代码中我们可以看出来它是来自Integer类中的一个静态内部类,有自己默认的无参构造函数。在static 块中将自己的属性cache 构造了一缓存数组,默认的范围是从 -128 到 127 我们也可以通过虚拟机的参数-XX:AutoBoxCacheMax来调整上限。

首先我们应该知道哪里用到了Cache ,我们才能分析出来如何很好的使用这个cache

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

到这里可能会有点奇怪辛辛苦苦构造的一个 cache 怎么就有了一个次 ? 其实当我们继续查看Inetger类所拥有的方法时,你会发现Inetger类他的主要功能有取最大值、最小值、位数、获取环境变量数值 、各种转换方法等;但是这些功能的前提到的各种静态工厂方法valueOf(); 举个栗子:

//从系统的property文件中拿出一个integer public static Integer getInteger(String nm, int val) { Integer result = getInteger(nm, null); return (result == null) ? Integer.valueOf(val) : result; } //返回一个指定进制 的数 public static Integer valueOf(String s, int radix) throws NumberFormatException { return Integer.valueOf(parseInt(s,radix)); } //将String字符串解码 public static Integer decode(String nm) throws NumberFormatException { int radix = 10; int index = 0; boolean negative = false; Integer result; if (nm.length() == 0) throw new NumberFormatException("Zero length string"); char firstChar = nm.charAt(0); // Handle sign, if present if (firstChar == '-') { negative = true; index++; } else if (firstChar == '+') index++; // Handle radix specifier, if present if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) { index += 2; radix = 16; } else if (nm.startsWith("#", index)) { index ++; radix = 16; } else if (nm.startsWith("0", index) && nm.length() > 1 + index) { index ++; radix = 8; } if (nm.startsWith("-", index) || nm.startsWith("+", index)) throw new NumberFormatException("Sign character in wrong position"); try { result = Integer.valueOf(nm.substring(index), radix); result = negative ? Integer.valueOf(-result.intValue()) : result; } catch (NumberFormatException e) { // If number is Integer.MIN_VALUE, we'll end up here. The next line // handles this case, and causes any genuine format error to be // rethrown. String constant = negative ? ("-" + nm.substring(index)) : nm.substring(index); result = Integer.valueOf(constant, radix); } return result; }

因此当遇到一些明确知道会涉及到较大数值的场景时,我们可以考虑尝试通过JVM 参数-XX:AutoBoxCacheMax来修改Integer 默认cache上限来优化我们的程序

Java中的异常处理机制

Exception 和 Error 都是继承了 Throwable 类,在 Java 中只有 Throwable 类型的实例才可以被抛出( throw )或者捕获( catch ),它是异常处理机制的基本组成类型。 Exception 和 Error 体现了 Java 平台设计者对不同异常情况的分类。 Exception 是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。 Error 是指在正常情况下,不大可能出现的情况,绝大部分的 Error 都会导致程序(比如 JVM 自身)处于非正常的、不可恢复状态。既然是非正常情况,所以不便于也不需要捕获,常 见的比如 OutOfMemoryError 之类,都是 Error 的子类。 Exception又分为 可检查 (checked)异常和 不检查 (unchecked)异常,可检查异常在源代码里必须显式地进行捕获处理,这是编译期检查的一部分。前面我介绍的不可查 的 Error ,是 Throwable 不是 Exception 。 不检查异常就是所谓的运行时异常,类似 NullPointerException 、 ArrayIndexOutOfBoundsException 之类,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕 获,并不会在编译期强制要求。 Throw early, catch late原则

throw 和throws 的区别

throw 是在方法内,表示抛出具体异常,则由该方法的使用者来处理异常。 Java 中只有throwabout的子类才可以被抛出 or 捕获

具体向外抛出的动作,所以它抛出的是一个异常实体类。若执行了Thow一定是抛出了某种异常 1.在捕获异常时需要尽量具体而不是 简单的 Catch Exception 2.只少使用logger 记录异常以方便后来的查找问题

Throws:

作用在方法的声明上,表示如果抛出异常,则由该方法的调用者来进行异常处理。主要的声明这个方法会抛出会抛出某种类型的异常,让它的使用者知道捕获异常的类型。出现异常是一种可能性,但不一定会发生异常。

讲讲MVC的思想

Spring中Bean的生命周期

创建和销毁两个过程 spring bean 的作用域: Singleton,这是Spring的默认作用域,也就是为每个IOC容器创建唯一的一个Bean实例。 Prototype,针对每个getBean请求,容器都会单独创建一个Bean实例。 如果是 Web 容器,则支持另外三种作用域: Request,为每个HTTP请求创建单独的Bean实例。 Session,很显然Bean实例的作用域是Session范围。 GlobalSession,用于Portlet容器,因为每个Portlet有单独的Session,GlobalSession提供一个全局性的HTTP Session。

AOP 动态代理

分布式ID

synchronized和ReentrantLock有什么区别呢?

最新回复(0)