1、抽象类和接口的对比
2、 Equals()方法
普遍回答是==比较的是内存地址,equals比较的是值。但不是很标准。
Object对象的equals的定义是这样的:
所以在Object中==和equals是没有任何区别的,是用来比较两个对象的引用是否相等,即是否指向同一个对象。
但在String中,重写的equals方法是这样定义的:
String类对equals方法进行了重写,用来比较指向的字符串对象存储的字符串是否相等。其他的一些诸如Double,Date,Integer等都对equals方法进行了重写用来比较指向的对象所存储的内容是否相等。
对于==,如果作用于基本类型的变量,则直接比较其存储的值是否相等;如果作用于引用类型的变量,则比较的是所指向的对象的地址。
对于equals方法,注意:equals方法不能作用域基本数据类型的变量。如果没有对equals方法进行重写则比较的是引用类型的变量所指向的对象的地址;诸如String、Date等对equals方法进行了重写的话,比较的是所指向的对象的内容。
3、Integer和int的区别
原始类型:byte,boolean,short,char,int,float,double,long
包装类型:Byte,Boolean,Short,Character,Integer,Float,Double,Long
Java基本类型占用的字节数:
1字节:byte,Boolean,byte范围是-128-127
2字节:short,char
4字节:int,float
8字节:long,double
1字节(byte)=8位(bits)
- Ingeter是int的包装类,int的初值是0,Ingeter的初值为null,int范围是-2^31 —— 2^31-1;
- 无论如何,Integer与new Integer不会相等。不会经历拆箱过程,new出来的对象放在堆,而非new的Integer常量则在常量池(方法区),它们的内存地址不一样,所以为false;
- 两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false。因为java在编译Integer i2 = 128的时候被翻译成:Integer i2 = Integer.valueOf(128);而valueOf函数会对-128到127之间的数进行缓存。
- 两个都是new出来的都为false,内存地址不一样。
-
Int和Integer比都为true,因为会把Integer自动拆箱为int再去比。
4、Static
- Static方法:由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说是没有this的,因为它不依赖于任何对象。在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
- Static变量:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候初始化,存在多个副本,各个对象拥有的副本互不影响。
- Static代码块:static块可以置于类中的任何地方,类中可以有多个static块,在类初次被加载的时候,会按照static块的顺序来执行每个static并且只会执行一次。
Java中static关键字不会改变成员的访问权限。Static不允许用来修饰局部变量。
在第一次创建一个类的对象或者第一次调用一个类的静态属性和方法时加载静态类。
类加载期间如果发现有静态属性就给对应的静态属性分配内存空间并赋值(在声明静态变量时不一定赋值),今后调用该类的静态属性时虚拟机会直接寻找该属性先前已经分配的内存空间地址,然后调用其值。基本数据类型的静态变量存在池里面。
5、String,StringBuffer和StringBuilder
String字符串常量,StringBuffer字符串变量(线程安全),StringBuilder(非线程安全)。
大部分情况StringBuilder> StringBuffer > String
String用final修饰是不可变的对象,因此在每次对String类型进行改变的时候都等于生成了一个新的String对象,所以它是线程安全的,然后将指针指向新的String对象,所以经常改变内容的字符串最好不要用String,因为每次生成对象会对系统性能产生影响,特别当内存中无引用对象多了以后,JVM的GC就会开始工作,那速度是一定会相当慢的。
而StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象,再改变对象引用。
所以字符串对象经常改变的情况下一般推荐使用StringBuffer。
大部分情况StringBuffer> String
StringBuffer上的主要操作是append和insert方法,可重载这些方法,以接受任意类型的数据。
StringBuilder不能保证同步,该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。
String name = ”I ” + ”am ” + ”chenssy ” ;在JVM眼中就是String name = ”I am chenssy ”
6、String(原文链接)
- 单独使用""引号创建的字符串都是常量,编译期就已经确定存储到String Pool常量池中;
- 使用new String("")创建的对象会存储到heap中,是运行期新创建的;
new创建字符串时首先查看池中是否有相同值的字符串,如果有,则拷贝一份到堆中,然后返回堆中的地址;如果池中没有,则在堆中创建一份,然后返回堆中的地址(注意,此时不需要从堆中复制到池中,否则,将使得堆中的字符串永远是池中的子集,导致浪费池的空间)! - 使用只包含常量的字符串连接符如"aa" + "aa"创建的也是常量,编译期就能确定,已经确定存储到String Pool中;
- 使用包含变量的字符串连接符如"aa" + s1创建的对象是运行期才创建的,存储在heap中;
7、final
- 修饰类,当用final去修饰一个类的时候,表示这个类不能被继承。
注意:
a. 被final修饰的类,final类中的成员变量可以根据自己的实际需要设计为fianl。
b. final类中的成员方法都会被隐式的指定为final方法。 - 修饰方法,被final修饰的方法不能被重写。
注意:
a. 一个类的private方法会隐式的被指定为final方法。
b. 如果父类中有final修饰的方法,那么子类不能去重写。 - 修饰变量
注意:
对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
8、BigDecimal
BigDecimal 由任意精度的整数非标度值 和32 位的整数标度 (scale) 组成。如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负scale 次幂。因此,BigDecimal表示的数值是(unscaledValue × 10-scale)。
计算机是二进制的。浮点数没有办法是用二进制进行精确表示。我们的CPU表示浮点数由两个部分组成:指数和尾数,这样的表示方法一般都会失去一定的精确度,有些浮点数运算也会产生一定的误差。如:2.4的二进制表示并非就是精确的2.4。反而最为接近的二进制表示是 2.3999999999999999。
注意:
- )尽量使用参数类型为String的构造函数。BigDecimal aString =new BigDecimal("1.22");
- BigDecimal都是不可变的,在进行每一步运算时,都会产生一个新的对象,所以在做加减乘除运算时千万要保存操作后的值。
BigDecimal a =new BigDecimal("1.22");
System.out.println("construct with a String value: " + a);
BigDecimal b =new BigDecimal("2.22");
a.add(b);//a还是1.22
BigDecimal c = a.add(b);