1.int和Integer的区别
1、Integer是int的包装类,int则是java的一种基本数据类型
2、Integer变量必须实例化后才能使用,而int变量不需要
3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值
4、Integer的默认值是null,int的默认值是0
5、Integer的值缓存范围为-128~127
延伸:
关于Integer和int的比较
1、由于Integer变量实际上是对一个Integer对象的引用,所以两个通过new生成的Integer变量永远是不相等的(因为new生成的是两个对象,其内存地址不同)。
Integer integer1 = new Integer(100);
Integer integer2 = new Integer(100);
System.out.println(integer1==integer2); false
2、Integer变量和int变量比较时,只要两个变量的值是向等的,则结果为true(因为包装类Integer和基本数据类型int比较时,java会自动拆包装为int,然后进行比较,实际上就变为两个int变量的比较)
Integer integer = new Integer(100);
int a = 100;
System.out.println(integer==a); true
3、非new生成的Integer变量和new Integer()生成的变量比较时,结果为false。(因为非new生成的Integer变量指向的是java常量池中的对象,而new Integer()生成的变量指向堆中新建的对象,两者在内存中的地址不同)
Integer integer3 = new Integer(200);
Integer j = 200;
System.out.println(integer3==j); false
4、对于两个非new生成的Integer对象,进行比较时,如果两个变量的值在区间-128到127之间,则比较结果为true,如果两个变量的值不在此区间,则比较结果为false
Integer a1 = 200;
Integer b1 = 200;
System.out.println(a1==b1); false
Integer a1 = 100;
Integer b1 = 100;
System.out.println(a1==b1); true
涉及的知识点:
1.java数据类型
基本数据类型:byte、int、short、long、float、double、char、boolean
引用数据类型:数组、类、接口
2.自动封箱和自动拆箱
自动装箱是将一个java定义的基本数据类型赋值给相应封装类的变量。
拆箱与装箱是相反的操作,自动拆箱则是将一个封装类的变量赋值给相应基本数据类型的变量。
2.equals和==的区别
比较对象是值变量:“==”常被用来比较基本数据类型(byte,int,short,long,float,double,char,boolean),变量直接存储的就是他们的值,所以“==”比较的就是他们的值,注意的是,基本数据类型不能用equals进行比较(equals是个函数,而基本类型不是对象)。
比较对象是引用型变量:“==” 比较的是两个变量在堆中存储的地址是否相同。equals表示的是两个变量是否对同一个对象的引用,即堆中的内容是否相同。==比较的是两个对象的地址,equals比较的是两个对象的内容,equals为true时,“==”不一定为true。
equals是object的一个方法,创建的对象均可调用object的equals方法,但是使用equals方法时,要对它进行重写,否则它和==比较的效果一样。
总结:
== : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不试同一个对象。
equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况(前面第1部分已详细介绍过):
情况1,类没有覆盖equals()方法。则通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象。
情况2,类覆盖了equals()方法。一般,我们都覆盖equals()方法来两个对象的内容相等;若它们的内容相等,则返回true(即,认为这两个对象相等)。
//object中定义的equals方法
public boolean equals(Object obj) {
return (this == obj);
}
3.Java面向对象的基本特征
- 继承 子类继承父类 ,子类可以获取到父类的属性和方法
注:关于子类能否继承父类的私有方法?
从语言角度上说:JDK官方文档明确说明子类不能继承父类的私有方法;
但从内存角度来说,jvm在实例化子类对象之前,会先在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者合起来形成一个子类对象。所以子类确实拥 有父类所有的属性和方法,但是父类中的私有方法子类无法访问。
- 封装
封装可以使类具有独立性和隔离性;保证类的高内聚。只暴露给类外部或者子类必须的属性和操作。类封装的实现依赖类的修饰符(public、protected和private等)
- 多态
多态是在继承的基础上实现的。多态的三个要素:继承、重写和父类引用指向子类对象。父类引用指向不同的子类对象时,调用相同的方法,呈现出不同的行为;就是类多 态特性。多态可以分成编译时多态和运行时多态。
- 抽象
提取现实世界中某事物的关键特性,为该事物构建模型的过程。对同一事物在不同的需求下,需要提取的特性可能不一样。得到的抽象模型中一般包含:属性(数据)和操作(行为)。这个抽象模型我们称之为类。对类进行实例化得到对象。
4. &和&&的区别
&:按位与 &&:逻辑与
&&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true整个表达式的值才是true。&&之所以称为短路运算是因为,如果&&左边的表达式的值是false,右边的表达式会被直接短路掉,不会进行运算。
例如在验证用户登录时判定用户名不是null而且不是空字符串,应当写为:username != null &&!username.equals(“”),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则会产生NullPointerException异常。注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。
5.值传递和引用传递
所谓的值传递对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。
引用传递一般是相对于对象型来说的,传递的是该对象在内存中保存的地址信息的一个副本,并不是原对象本身,原对象本身存放在堆中。
6.Java中的方法重写(Overriding)和方法重载(Overloading)
方法覆盖:发生在子类和父类之间。子类重新定义了父类的方法,方法覆盖必须有相同的方法名,参数列表以及返回值类型。子类要比父类被重写的方法有更好的访问,不能声明比父类更多的异常
方法重载:同一类中两个或多个方法名相同但是参数列表(参数个数,参数类型)不同的方法,对返回结果不做要求。
重写和重载是多态的实现方式,重载实现的编译时的多态性,后者实现的是运行时的多态性。
7.接口和抽象类的 区别
抽象方法是一种特殊的方法:它只有声明,没有具体的实现。abstract void a(); 抽象方法必须用abstract关键字进行修饰。
如果一个类中具有抽象方法,那么这个类就是抽象类。一个类中只要包含抽象方法,那么这个类就是抽象类,抽象类也可以包含非抽象方法。一个类中没有抽象方法,它只要被abstract关键字修饰,那么它也是抽象方法。抽象类中含有无具体实现的方法,所以抽象类不能被实体化。
包含抽象方法的为抽象类,并不意味着,抽象类中只能具有抽象方法,和普通类一样,抽象类同样可以拥有成员变量和普通的成员方法。
普通类和抽象类的区别
1. 抽象类必须要为public或者protected,因为要对它进行继承,不能使用private,若不写,默认为public。
2.抽象类不能被实体化,普通类可以。
3.如果一个类继承一个抽象类,则子类必须实现抽象类中的所有抽象方法。如果子类没有实现父类的所有抽象方法,需要把子类也定义为abstract类。
接口:用interface修饰的, 接口中可以包含变量和方法,变量被隐式地指定为public static final变量(只能是public static fianl)。而方法被隐式指定为public abstract(用其他关键字,private,protected,static,final会报编译错误),所有接口中的方法只能是抽象方法。接口不能被实体化。
接口和抽象类的区别
参数 | 抽象类 | 接口 |
默认的方法实现 | 它可以有默认的方法实现 | 接口完全是抽象的,根本不存在方法的实现 |
实现 |
子类使用extend关键字来继承抽象类。如果子类不是 抽象类的话 它需要提供抽象类中所有声明的抽象方法的实现。 |
子类使用关键字implement来实现接口。 它需要提供接口中所有声明的方法的实现。 |
构造器 | 抽象类可以有构造器(从语法的角度来说,抽象类必须有构造方法,而接口严禁有构造方法,这本身也说明了它们性质的不同。抽象类是一个类,别的类是用关键字 extends 来继承下来,并扩展的,有非常强的is-a的关系,这种关系一般来说符合里氏代换原则。而接口,是被其他类用关键字 implements 来实现接口定义的方法的) | 接口不能 有构造器(接口是一种规范,被调用时,主要关注的是里边的方法,而方法是不需要初始化的) |
与正常java类的区别 | 除了不能实例化之外,与普通类没有区别 | 接口是完全不同的类型 |
访问修饰符 | 抽象类可以被public、protected和default修饰符修饰 | 接口默认的修饰符为public,不可以使用其他修饰符 |
main方法 | 抽象类中可以有main方法。 | 接口中没有main方法 |
多继承 | 抽象类只能继承一个类和实现多个接口 | 接口只能继承一个或多个其他接口 |
速度 | 抽象类比接口速度要快 | 接口是稍微有点慢的,它需要时间去寻找在类中实现的方法 |
添加新方法 | 可以给他提供默认的实现 | 需要改变实现该接口的类 |
8.final、finally和finalze的区别
final:用final进行声明属性、方法和类,分别表示属性不可变,方法不可重写,类不可继承。
finally:异常处理语句结构中的一部分,表示总是执行。
try { } catch (Exception e) {
// TODO: handle exception
}finally { }
finalze:是object类中的一个方法,当垃圾回收器将要回收对象所占内存之前被调用,即当一个对象被虚拟机宣告死亡时会先调用它finalize()方法,让此对象处理它生前的最后事情(这个对象可以趁这个时机挣脱死亡的命运)。
flnalze的详细解释https://www.cnblogs.com/Smina/p/7189427.html
9.Object类中的方法。
object类是java中所有类的祖先,是所有类的基类,Object具有哪些属性和行为,是java语言设计背后的思维体现。
object类为与java.lang包中,java.lang包包含着java最基础和核心的类,在编译时会自动导入。
Object类*有13种方法:getClass()、hashCode()、equals()、clone()、toString()、notify()、notifyall()、wait()、finalize()
clone():clone函数返回的是一个引用,指向的是新的clone出来的对象,此对象与原对象分别占用不同的堆空间。
getClass():getClass()也是一个native方法,返回的是此Object对象的类对象/运行时类对象Class<?>。效果与Object.class相同。
notify()、notifyall()、wait() :这几个方法主要用于java多线程之间的协作。既然是作用于多线程中,为什么却是Object这个基类所具有的方法?原因在于理论上任何对象都可以视为线程同步中的监听器,且wait(...)/notify()|notifyAll()方法只能在同步代码块中才能使用。
wait(...)方法调用后当前线程将立即阻塞,且适当其所持有的同步代码块中的锁,直到被唤醒或超时或打断后且重新获取到锁后才能继续执行;
notify()/notifyAll()方法调用后,其所在线程不会立即释放所持有的锁,直到其所在同步代码块中的代码执行完毕,此时释放锁,因此,如果其同步代码块后还有代码,其执行则依赖于JVM的线程调度。
10.hashcode()和equals()区别
https://www.cnblogs.com/skywang12345/p/3324958.html
1.若重写了equals(Object obj)方法,则有必要重写hashCode()方法。
2.若两个对象equals(Object obj)返回true,则hashCode()有必要也返回相同的int数。
3.若两个对象equals(Object obj)返回false,则hashCode()不一定返回不同的int数。
4.若两个对象hashCode()返回相同int数,则equals(Object obj)不一定返回true。
5.若两个对象hashCode()返回不同int数,则equals(Object obj)一定返回false。
6.同一对象在执行期间若已经存储在集合中,则不能修改影响hashCode值的相关信息,否则会导致内存泄露问题。