1、java中==和equals和hashCode的区别
(1)“==”
①对于基本数据类型来说,比较的是两个变量数据的内容是否相等;
②对于指向对象的的变量,比较的是两个变量是否指向同一个存储单元,即比较的是变量指向的对象的首地址是否相等
(2)“equals”
JAVA中所有类都是继承Object基类,这个基类中所有的equals方法初始行为是比较两个对象的内存地址,但在String,Integer,Date类中被覆盖,此时比较的是对象的内容
(3)“hashCode”
①当往集合(集合中不允许重复元素存在)中存对象,如何判断集合中是否已经存在该对象。当集合中数据较多时,使用equals方法会效率很低。往集合中添加新对象时,先调hashcode()方法获取hashcode值,实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值,如果在这个table里面没有该hashcode值,直接存进集合。如果存在,则调用equals和新元素进行比较,如果相同则不存,不相同则散列其他地址。
②对于HashSet、HashMap以及HashTable这样的对象来说
A)两个对象,如果调用equals方法得到的结果为true,则两个对象的hashcode必定相等
------->因为比较的是地址,相等说明为同一对象
B)如果equals方法得到的结果为false,则两个对象的hashcode值不一定不同
------>不同对象hashcode值可能相同,就是所说的地址冲突
C)如果两个对象的hashcode值不等,则equals方法得到的结果必定false
-------> hashcode值不等说明为两个对象(同一个对象的hashcode值必定相等,因为集合中不能有重复的元素存在),
所以equals结果必定为false
D)如果两个对象的hashcode值相等,则equals方法得到的结果未知
------> hashcode值相等,可能为同一对象,可能是两个对象
2、int、char、long各占多少字节数
1字节:byte、boolean
2字节:short、char
4字节:int、float
8字节:long、double
3、Integer与Int区别
(1)Integer是Int提供的封装类,而int是Java的基本数据类型
(2)Integer默认值为null,而int默认值为0
(3)声明为Integer的对象需要实例化,声明为int的变量不需要实例化
(4)Integer是对象,用一个引用指向这个对象,而int是基本类型,直接存储数组
4、Java多态
5、String、StringBuffer、StringBuilder区别
(1)String 字符串常量,StringBuffer字符串变量(线程安全)、StringBuilder字符
串变量(非线程安全)
(2)区别:
String是不可变的对象,每次对String类型进行改变时等同于生成了一个新的String对象,而StringBuffer结果则不一样,每次结果都会对StringBuffer对象本身进行操作,而不是生成新的对象,再改变对象引用。大部分情况下StringBuffer > String,
Java.lang.StringBuffer线程安全的可变字符序列,类似于String的字符串缓冲区,但不能修改,通过方法调用可以改变序列的长度和内容,可将字符串缓冲区安全的用于多个线程。大部分情况下,StringBuilder>StringBuffer,StringBuffer在append方法前增加了一个syncronized修饰符,起到同步作用,降低了执行效率,两者方法基本相同
6、什么是内部类?内部类的作用?
回答参考这篇博客 :https://www.cnblogs.com/dolphin0520/p/3811445.html
(1)内部类的概念:
将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。一般来说包括四种:成员内部类、局部内部类、匿名内部类和静态内部类。
①成员内部类:可以无条件访问外部类的所有成员属性和方法(包括private成员和静态成员),当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员,要访问外部类的成员,需要以下面的形式访问:外部类.this.成员变量、外部类.this.成员方法。外部类想访问成员内部类,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问。成员内部类用private修饰,则只能在外部类的内部访问,如果用public修饰,任何地方都能访问,用protected修饰,只能在同一个包下或者继承外部类的情况下访问,如果是默认访问权限,则只能在同一个包下访问。
②局部内部类:定义在一个方法或者一个作用域里面的类,与成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内,局部内部类像是方法里面的一个局部变量
一样,不能有public、protected、private、static修饰符
③匿名内部类:唯一没有构造器的类,大部分匿名内部类用于接口回调,匿名内部类用于继承其他类或者实现接口,不需要增加额外的方法,只是对继承方法的实现或重写
④静态内部类:定义在另一个类里面的类,只不过在类的前面多加了一个字static
静态内部类不能访问外部类的非static变量或者方法,在没有外部类对象的情况下,可以创建静态内部类的对象,而外部类的非static变量或者方法是依赖于外部类的具体对象,所以静态内部类不能访问外部类非static变量或方法
注:局部内部类和匿名内部类只能访问局部final变量,假如:
public class Test {
public static void main(String[] args) {
}
public void test(final int b) {
final int a = 10;
new Thread(){
public void run() {
System.out.println(a);
System.out.println(b);
};
}.start();
}
}
如果a变量不是final类型,当test方法执行完毕以后,变量a的声明周期就结束了,而Thread的声明周期很可能没结束,Thread里面的run方法访问a变量就变得不可能了,所以如果局部变量的值在编译时就可以确定,则直接在匿名内部类里创建一个拷贝,如果局部变量的值无法在编译期间确定,则通过构造器传参的方式对拷贝进行初始化赋值,所以run方法中访问的a变量并不是test方法中的变量a,而是匿名内部类中a变量的拷贝值。这样就解决了声明周期不一致的问题。所以a是不能修改的,否则会造成拷贝进匿名内部类的值和变量值不一致的问题,所以变量必须为final类型
(2)内部类的好处:
①每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响
②方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏
③方便编写事件驱动程序
④方便编写线程编码
(3)成员内部类,必须先产生外部类的实例化对象,才能产生内部类的实例化对象,而静态
内部类不用产生外部类的实例化对象即可产生内部类的实例化对象,
创建静态内部类对象的方法:外部类类名.内部类类名 xxx = new 外部类类名.内部类类名
创建成员内部类对象的方法:外部类类名.内部类类名 xxx = 外部类对象名.new 内部类类名
4、抽象类和接口的区别
接口是对动作的抽象,抽象类是对根源的抽象,抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。说明,他们都是人。
人可以吃东西,狗也可以吃东西,你可以把“吃东西”定义成一个接口,然后让这些类去实现它.关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。
区别
(1)接口是对动作的抽象,抽象类是对根源的抽象。关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口
(2)接口是抽象类的变体,接口中所有的方法都是抽象的,而抽象类是声明方法的存在而不去实现他的类
(3)接口可以继承,抽象类不行
(4)接口定义方法不能实现,抽象类可以实现部分方法
(5)接口中基本数据类型为static而抽象类不是的
8、抽象类的意义
(1) 为子类提供一个公共的类型
(2)封装子类中重复内容(成员变量和方法)
(3)定义有抽象方法,子类虽然有不同的实现,但该方法的定义是一致的
抽象类往往用来表征我们在对问题领域进行分析、 设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。比如:如果我们进行一个图形编辑软件的开发,就会发现问题领域存在着圆、 三角形这样一些具体概念,它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域是不存在的,它就是一个抽象概念。正是因为抽象的概念 在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的
简单的来说:
1 优先定义接口
2 如果有多个接口实现有公用的部分,则使用抽象类,然后集成它。
10、抽象类是否可以没有方法和属性?
抽象类可以不包含抽象方法和属性,但包含抽象方法的一定是抽象类,抽象类的作用在于子类对其的继承和实现,也就是多态;抽象类可以没有抽象方法,但是如果你的一个类已经声明成了抽象类,即使这个类中没有抽象方法,它也不能再实例化,即不能直接构造一个该类的对象。如果一个类中有了一个抽象方法,那么这个类必须声明为抽象类,否则编译通不过。而没有抽象方法的抽象类的存在价值在于:实例化了没有意义,因为类已经定义好了,不能改变其中的方法体,但是实例化出来的对象却满足不了要求,只有继承并重写了他的子类才能满足要求。所以才把它定义为没有抽象方法的抽象类
11、接口的意义
接口是一种规范对于软件开发是类似的:
按照接口规范进行方法调用,就能获得所期望的功能
按照接口规范实现接口的的方法,就能提供所期望的功能
软件开发大多是一个协作性的工作:电器和插座分别是不同人完成的,有了接口大家就能分头开干,都按照接口来办事,各自做完就能轻松地整合到一起。各部分的测试也更加方便。
软件需要不断演化:今天你用了公牛的插座,过了一年你可能换个西门子的插座,要做没有这套国家接口标准,各自为政,那估计你是换不了插座了。你想想,咱们每次去美国出差,都得带个转接头,否则就跪了,多不方便啊,因为接口规范不同啊!(这些个转接头你是不是闻道一种浓浓的Adapter模式的味道)。