Java程序员面试核心知识--Java基础知识(一)

目录

一、Java程序初始化顺序

二、Java的Clone方法作用

三、 OverLoad(重载)与Override(重写)区别

四、abstract class(抽象类)与interface(接口)的异同

五、String、StringBuffer、StringBuilder区别

六、“==”、equals和hashCode的区别

七、字符串创建与存储的机制


一、Java程序初始化顺序

结论:父类静态变量->父类静态代码块->子类静态变量->子类静态代码块->父类非静态变量->父类非静态代码块->父类构造方法->子类非静态变量->子类非静态代码块->子类构造方法

代码例题,请写出下面程序的运行结果

package com.alphamilk.Example101;class Father{static String staticString = "a";static {System.out.println(staticString);System.out.println("b");}public  String NonString = "c";{System.out.println(NonString);System.out.println("d");}
}
class Son extends Father{static String SonstaticString = "e";static {System.out.println(SonstaticString);System.out.println("f");}public  String SonNonString = "g";{System.out.println(SonNonString);System.out.println("h");}
}
public class javaDemo {public static void main(String[] args) {Son son = new Son();}
}


二、Java的Clone方法作用

        由于Java在处理基本数据类型(如int、double、char等)时候,都是采用按值传递,除此之外的数据类型都是按照引用传递方式执行

这就会导致数据类型的备份出现问题,基本数据类型可以通过值传递快速备份,而对象引用会传递对象的地址,这样会导致对备份的操作影响到原本的数据。如下案例:

// 其它类型数据
class Person{public String name;public int age;Person(String name ,int age){this.name = name;this.age = age;}@Overridepublic String toString() {return "name:"+name+"  age:"+age;}
}
public class JavaDemo {public static void main(String[] args) {
//        基本数据类型与备份int a  = 10;int b;b = a;
//        对备份操作b = 100;System.out.println(a);System.out.println(b);
//        其它类型与"="引用Person person = new Person("小红",100);Person person1 = person;
//        对备份进行操作person1.name = "小黄";System.out.println(person);System.out.println(person1);}
}

可以看到由于对象类型的“=”是引用传递,传递的是对象的地址,所以对备份的操作实际上就是对本体的操作.

所以想要使用备份就需要Object类中的Clone方法。而Object类是所有类的父类,所以可以如下实现

1.实现Cloneable接口 2.覆写Clone方法 3.调用方法

//1.实现 Cloneable 接口
class Person implements  Cloneable{public String name;public int age;Person(String name ,int age){this.name = name;this.age = age;}@Overridepublic String toString() {return "name:"+name+"  age:"+age;}
//   2. 实现克隆方法public Person Clone(){Person per  = null;try {
//            强制转型per = (Person)super.clone();}catch (CloneNotSupportedException e){e.printStackTrace();}return per;}
}
public class JavaDemo {public static void main(String[] args) {Person person = new Person("小红",100);
//        3.调用Clone()方法Person person1 = person.Clone();//        对备份对象进行操作person1.name = "小黄";person1.age=12;
//        输出对象System.out.println(person);System.out.println(person1);}
}

注意:上述代码克隆是在对象中仅存在基本数据类型下,这样的拷贝被称为浅拷贝。而一旦对象中还存在其它对象,则需要用深拷贝实现拷贝内容.

Clone分为浅拷贝和深拷贝

浅拷贝:仅仅拷贝对象中只存在基本数据类型

深拷贝:可以拷贝对象中包含的对象

深拷贝如下案例:

class Student implements Cloneable{
//    基本数据类型int id;
//    其它引用对象类型Dateprivate Date birthDay = new Date();public Date getBirthDay() {return birthDay;}
//    更改BirthDay方法public void  ChangedBirthDay(){long intervalTime = 3600*30;long time  =  birthDay.getTime();birthDay.setTime(time+intervalTime);}//    覆写克隆方法public  Student Clone(){Student student = null;
//        浅层拷贝try {student = (Student) super.clone();} catch (CloneNotSupportedException e) {throw new RuntimeException(e);}
//        深层拷贝student.birthDay = (Date) this.getBirthDay().clone();return student;}@Overridepublic String toString() {
//        输出对象return "Student's id:"+id+" birthday is " +birthDay;}
}
public class JavaDemo2 {public static void main(String[] args) {Student student1 = new Student();student1.id = 10;Student student2 = student1.Clone();student2.id = 11;student2.ChangedBirthDay();System.out.println(student1);System.out.println(student2);}

深层拷贝相比与浅层拷贝,需要额外对引用对象中其它对象进行拷贝。


三、 OverLoad(重载)与Override(重写)区别

overload 与 override 都是Java多态性的不同表现,其中overload是类中多态性的显现,

Overload重载

重载指的是同一个类中有多个方法名称相同,但是参数不同的方法,因此可以在编译时候就确定具体调用哪个方法。它是一种编译时候的多态,重载可以看作一个类的多态。

Override重写

子类可以重写父类的方法,因此同样的方法在父类和子类中有着不同的表现形式,在Java语言中,基类的引用变量不仅可以指向其实现类的实例对象,也可以指向其子类的实例对象。同样,接口的引用变量中可以指向其实现类的实例对象。

案例代码:

class Person{String race;
//    父类方法public String printfInfo(String race){return "种族"+race;}
}
class Student extends  Person{int id;String name;
//    实现构造方法重载(OverLoad)//    1.无参构造方法Student(){}
//    2.单参构造方法Student(String name){this.name = name;}
//    3,多参构造Student(String name ,int id){this.name = name;this.id = id;}
//    覆写方法/** 注意,覆写时候参数也需要一致*/@Overridepublic String printfInfo(String race) {return "种族"+race+" , 名称:"+name +" id"+id;}
}
public class JavaDemo {public static void main(String[] args) {Student student = new Student("Alpha",01);System.out.println(student.printfInfo("人类"));}
}

区别:

1.覆写是子类和父类之间的关系,是垂直关系,而重载是同一个类中方法之间的关系,是水平关系。

2.覆写只能由一个方法或者一对方法产生关系,方法的重载是多个方法之间的关系。

3.覆写要求参数列表相同,而重载要求参数列表不同

4.覆写关系中,调用方法体是根据对象的类型(对象对应存储空间类型)来决定的,而重载关系是根据调用时的实参列表和形参列表来选择方法体的。


四、abstract class(抽象类)与interface(接口)的异同

抽象类

        如果一个类中包含抽象方法,那么这个类就是抽象类。在Java中可以通过某些类或者是类中的方法声明为abstract(abstract只能用来修饰类或者方法,不能用来修饰属性)来表示一个类是抽象类。只要包含一个抽象方法的类就必须声明为抽象类,抽象类可以仅仅申明方法的存在而不去实现它,被声明为抽象的方法不能包含方法体。在实现的时候,必须包含相同的或者更低的访问级别(public -> protectd ->private ).抽象类在使用的过程中不能被实例化,但是可以创建一个对象使其指向具体子类的一个示例,抽象类的子类为父类中所有的抽象方法提供具体的实现。否则子类也将是抽象类。

接口

        接口就是一个方法的集合,在Java中,接口是通过关键字interface来实现的,在Java8之前,接口中既可以定义方法也可以定义变量,其中变量必须是public、static、final的。而且方法必须是public abstract 的。由于这些修饰符都是默认的。

        在Java8之后,可以通过关键字default给接口中的方法添加默认实现,此外接口中还可以定义静态方法。

案例代码:

interface category{
//    输出物种信息public void printInfo();
}
interface Breath{
//    生物进行呼吸public void Breath();
}
abstract class behavior{
//    定义抽象方法public abstract void shout();
//    定义普通方法public void jump(){System.out.println("进行跳跃");}
}
//只能继承一个抽象类
//但是能继承多个接口
class Person extends behavior implements Breath,category{//    覆写抽象类中的抽象方法@Overridepublic void shout() {System.out.println("人类进行嚎叫");}//    实现接口category中的方法@Overridepublic void printInfo() {System.out.println("种族,人类");}
//    实现接口Breath方法@Overridepublic void Breath() {System.out.println("呼吸类型:有氧呼吸与无氧呼吸");}
}
public class JavaDemo  {public static void main(String[] args) {Person person = new Person();
//        执行覆写的方法person.printInfo();person.Breath();person.shout();}
}

不同点

抽象类

  1. 抽象类只能被继承(通过extend),并且一个类只能继承一个抽象类
  2. 抽象类强调所属关系,其设计理念为is-a关系。
  3. 抽象类更倾向于充当公共类的角色,不适与日后重新对立面的代码进行修改。
  4. 除了抽象方法以外,抽象类中还可以包含具体数据和具体方法(可以由方法的实现)。
  5. 抽象类不能被实例化,其子类如果实现了继承中抽象类中的抽象方法后可以,实例化子类,否则子类也是抽象类不能被实例化。

接口

  1. 接口需要通过实现(implements),一个类可以实现多个接口
  2. 接口用于实现比较常用的功能,以便于日后的维护和方法的增删。
  3. 接口不是类,而是一种对类的一组需求描述,这些类需要遵循接口描述的统一格式进行定义。
  4. 接口中所有的方法都是public的,因此,再实现接口的类中必须把方法声明为public,因为默认类中访问属性是包可见的。而不涉及public,这就相当于在子类中降低了方法的可见性,会导致编辑错误。

五、String、StringBuffer、StringBuilder区别

在Java中,可以操作字符串的有几大类,包括String、StringBuffer、StringBuilder。

        String是不可变类,也就意味着一旦String对象一旦创建,其值无法被改变,而StringBuffer是可以改变的。所以当一个字符串需要经常修改的时候,最好用StringBuffer来实现。因为不可变类,其值在修改的时候,其实原来的数据并没有被删除,而是堆上创建了一个新的不可变类String的对象,并且栈上对象指向了新的对象,所以如果字符串大量修改的话,就会产生大量的浪费资源的无用对象。最后被垃圾回收器回收。虽然这在小的项目里影响微乎其微,但是在大项目中是会有非常大的效率问题。

        StringBuilder也是可以被修改的字符串,与StringBuffer相似,都是字符串的缓冲区,但是StringBuilder是线程不安全的。如果只是在单线程的情况下进行操作,那么StringBuilder的效率是最快的。而多线程使用的时候StringBuffer使用是最好的。因为StringBuffer在有需要的时候可以进行方法的同步。

        String与StringBuffer还有一点不同是在于初始化对象上,String有两种初始化方式第一种是直接赋值,第二种是通过构造函数赋值,而StringBuffer只能通过构造函数创建对象。

使用的案例代码:

public class JavaDemo {public static void main(String[] args) {
//        创建有序map,查看效率排名Map<Long,String> map = new TreeMap<>();//        String的两种初始化对象方式String a ="String A";String b =new String("String B");//        StringBuffer唯一初始化对象方式StringBuffer buffer = new StringBuffer("String C");
//        StringBuilder初始化方式StringBuilder builder = new StringBuilder("String D");//        单线程下分别测试效率
//        String字符串long start = System.currentTimeMillis();for (int i = 0;i<10000;i++){a = a + "Add String";}long end = System.currentTimeMillis();long internal1 = end - start;map.put(internal1,"String类型运行时间");//       StringBufferlong start2 = System.currentTimeMillis();for (int i=0;i<10000;i++){
//            调用StringBuffer内方法append,即添加字符串buffer = buffer.append("Add String");}long end2 = System.currentTimeMillis();long internal2 = end2 - start2;map.put(internal2,"StringBuffer类型运行时间");//        StringBuilderlong start3 = System.currentTimeMillis();for (int i=0;i<10000;i++){builder = builder.append("Add String");}long end3 = System.currentTimeMillis();long internal3 = end3 - start3;map.put(internal3,"StringBuilder类型运行时间");System.out.println(map);}
}

可以多次运行代码或者提高循环次数,查看平均值

单线程保证线程安全下 效率速度: StringBuilder>StringBuffer>String


六、“==”、equals和hashCode的区别

        “==”运算符在基本数据类型中是用于判断两个变量的值是否相同,但是如果两个变量是引用数据类型,那么“==”就是两个变量对应的引用地址的比较。

        equals是Object类中提供的方法,由于所有类都继承了Object主类,所以所有对象都是可以调用equals方法。相比于“==”运算符,equals方法的特殊之处就是在于它是可以被覆盖的,也就意味着它并不是比较引用的地址,而是比较对象中的属性。

        hashCode方法是从Object类中继承过来的,他也是用来鉴定两个对象是否相等。Object类中的hashCode()方法返回对象在内存中的地址并转换成一个int值,所以如果没有重写hashCode()方法,任何对象的hashCode方法都是不相等的。也即是哈希值唯一的

请你写出下面程序的执行结果:

class Person{String name;Person(String name){this.name = name;}
}
public class JavaDemo {public static void main(String[] args) {String a = new String("content");String b = new String("content");String c = "content";String d = "content";System.out.println("1:"+ (a==b));System.out.println("2:"+a.equals(b));System.out.println("3:"+(c == b));System.out.println("4:"+ (c == a));System.out.println("5:"+ (d == c));int base1 = 1 ,base2 = 1;Integer integer = 1;Integer integer1 = 1;System.out.println("6:"+ (base1==base2));System.out.println("7:"+ integer1.equals(integer));Person person = new Person("张三");Person person1 = new Person("张三");System.out.println("8:"+(integer.hashCode() == integer1.hashCode()));System.out.println("9:"+(c.hashCode() == a.hashCode()));System.out.println("10:"+(person.hashCode() == person1.hashCode()));}
}

注意:

  9:true 解释 --String 类是一个特殊的类,它有一个特殊的属性,即字符串常量池(String Pool)。当我们使用字面量创建字符串时,例如 String c = "content",Java会首先检查字符串常量池中是否已经存在相同内容的字符串,如果存在,则直接返回该字符串的引用;如果不存在,则在常量池中创建一个新的字符串对象,并返回其引用。

因此,在这段代码中,虽然 ab 是通过 new 关键字创建的两个不同的字符串对象,但它们的内容相同。而 cd 则是通过字面量创建的字符串,它们的内容也相同。由于字符串常量池的存在,cd 实际上是指向同一个字符串对象的引用,因此它们的地址是相同的。

   10:true解释 --对于 Integer 类型的对象,Java在内部维护了一个缓存池,用于缓存-128 ~ 127之间的整数对象。当我们通过 Integer.valueOf() 方法创建一个整数对象时,如果该整数在缓存池中已经存在,则直接返回该整数对象的引用;否则,在堆内存中创建一个新的整数对象,并将其加入到缓存池中,然后返回其引用。


七、字符串创建与存储的机制

在Java语言中,对String对象提供给了专门的存储机制。

public class StringPool {public static void main(String[] args) {//           第一种存储
//        将abc放到常量区abc,在编译时候产生String s = "abc";
//        将ab与c转为字符串常量“abc”并存在常量区String s1 = "ab"+"c";//            第二种存储
//        在堆中创建新的对象,堆中对象指向常量区String s2 = new String("abc");String s3 = new String("abc");//        分别输出四个常量地址System.out.println("s地址"+s.hashCode());System.out.println("s1地址"+s1.hashCode());System.out.println("s2地址"+s2.hashCode());System.out.println("s3地址"+s3.hashCode());}
}

第一种存储String s = "abc"

        在当创建一个字符常量的时候,会首先在字符串常量池中进行查找是否已经有相同的字符串常量。具体原理就是通过调用方法equals方法进行一 一匹配 ,如果不存在则需要先进行创建一个对象,然后将其加入字符串池中,再将它引用返回。而如果存在的话,直接获取对其的引用。而能够设置一个常量池的原因在于String类是一个不可变类,无法对其进行修改,日常对其进行修改本质是创建了一个新的字符串。

第二种存储String s1 = new String("abc");

        有区别第一种,第二种存储需要对其操作进行拆分,其多了一个new操作,这个操作是在堆上创建一个对象,并将值存放在堆中。是独立进行存储的,与常量池无关。

从分析中可以看出,在创建字符串对象时候,会根据不同的情况来确定字符串是存储在堆中还是常量池中。而intern方法就是用于将字符串存入常量池中。 所以通过intern方法可以将new关键字创建堆内的字符串对象存入字符串常量池中。

但是要注意的是intern方法随着JDK的更新,方法也随着更新。以下是其JDK1.6以下和JDK1.7以后的一些区别。

  • 在 JDK 1.6 及之前的版本中,调用 intern() 方法会将字符串复制一份到字符串常量池,并返回字符串常量池中的引用。如果字符串常量池中已经存在相同值的字符串,intern() 方法会返回常量池中的引用;否则,会在常量池中创建一个新的实例并返回该引用。
  • 而在 JDK 1.7 及之后的版本中,调用 intern() 方法会检查字符串常量池中是否存在相同值的字符串。如果存在,则返回常量池中的引用;如果不存在,则将字符串的引用直接存储到字符串常量池中,并返回该引用。换句话说,对于 JDK 1.7 及之后的版本,如果原始字符串已经在常量池中存在,调用 intern() 方法不会创建新的实例,而是直接返回常量池中的引用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/127481.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3D RPG Course | Core 学习日记三:Navigation智能导航地图烘焙

前言 前面我们已经绘制好了一个简单的地图场景&#xff0c;现在我们需要使用Navigation给地图做智能导航&#xff0c;以实现AI自动寻路&#xff0c;以及设置地图的可行走区域以及不可行走区域&#xff0c;Navigation的基础知识、原理、用法在Unity的官方文档&#xff0c;以及网…

【23真题】难!均79分!211题目强过985!

今天分享的是23年海南大学838的信号与系统试题及解析。 本套试卷难度分析&#xff1a;22年海南大学838考研真题&#xff0c;我也做过&#xff0c;若有需要戳这里自取&#xff01;平均分为80-90左右&#xff0c;最高分为133分。本套试题难度中等偏上&#xff0c;题量不多&#…

瓦斯抽采VR应急救援模拟仿真系统筑牢企业安全生产防线

矿工素质对安全生产的影响很大。传统的煤矿安全事故培训出于条件差、经验少加上侥幸心理&#xff0c;导致其在教学内容时过于简单且不切合实际&#xff0c;无法真正发挥培训作用。瓦斯检查作业VR模拟实操培训通过真实还原煤矿作业环境&#xff0c;让受训者身临其境地进入三维仿…

chatgpt接口调用

在线接口文档&#xff1a; https://app.apifox.com/invite?tokensymrLP7sojF6N31kZqnpZ 接口地址 https://chat.xutongbao.top/api/light/chat/createChatCompletion 请求方式 POST 请求参数 token String, 必须 prompt Array, 必须 例子一&#xff1a; 包含上下文 [ { "…

golang 发起 http 请求,获取访问域名的 ip 地址(net, httptrace)

前言 今天碰到了个需求&#xff0c;我要知道程序对外访问的 http 请求域名的 ip 地址。 直接查看 golang 的 net/http 包&#xff0c;发现 Response 中并没有我想要的 ip 信息。 考虑到在 OSI 七层模型中&#xff0c;ip 是网络层协议&#xff0c;而 http 是应用层协议。去翻…

NSGA-II 遗传多目标算法(python示例)

一、前言 最近在准备毕业论文&#xff0c;研究了一下主流的多目标算法&#xff0c;对于NSGA-II&#xff0c;网上大部分代码是全部是面向过程来实现的&#xff0c;本人更喜欢采用面向对象的方式&#xff0c;故采用python面向对象实现了一个示例&#xff0c;实现了对于二元多目标…

vue el-table-column 修改一整列的背景颜色

目录 修改表头以及一整列数据的背景颜色&#xff0c;效果如下&#xff1a; 总结 修改表头以及一整列数据的背景颜色&#xff0c;效果如下&#xff1a; 修改表头背景颜色&#xff1a;在el-table绑定header-cell-style 修改一整列的数据背景颜色&#xff1a;在el-table绑定:cel…

机器学习---支持向量机的初步理解

1. SVM的经典解释 改编自支持向量机解释得很好 |字节大小生物学 (bytesizebio.net) 话说&#xff0c;在遥远的从前&#xff0c;有一只贪玩爱搞破坏的妖怪阿布劫持了善良美丽的女主小美&#xff0c;智勇双全 的男主大壮挺身而出&#xff0c;大壮跟随阿布来到了妖怪的住处&…

美观且可以很方便自定义的MATLAB绘图颜色

函数介绍 主函数是draw_test&#xff0c;用于测试函数。 draw_h是函数&#xff0c;用于给Matlab提供美观且可以很方便自定义的绘图颜色。 draw_h函数介绍 这是一个带输入输出的函数&#xff0c;输入1/2/3&#xff0c;输出下面三种颜色库的配色&#xff0c;每种库均有五种颜色…

Java学习_day07_类的构造器代码块继承封装多态

文章目录 构造器格式注意点使用 代码块格式注意 继承格式注意点 封装包声明包导包注意点 访问修饰符 多态格式注意点代码演示 构造器 Java中每个类都至少有一个构造器&#xff0c;当程序员没有明确编写构造器时&#xff0c;Java编译器会自动为类添加一个无参的构造器。构造器通…

分享一下在微信小程序怎么发送优惠券

在微信小程序中&#xff0c;发送优惠券是一种常见的营销手段&#xff0c;它能够吸引用户购买商品或服务&#xff0c;提高销售业绩和用户忠诚度。本文将介绍在微信小程序中如何发送优惠券&#xff0c;包括优惠券的种类、发放方式、制作和推广等&#xff0c;帮助您更好地利用优惠…

沉痛悼念科研分公司

今天上班途中&#xff0c;遇到了上家公司的同事王强。他正准备去体检中心体检。几句寒暄之后&#xff0c;得知他是要入职选煤公司了。 我们所在的公司比较大&#xff0c;总公司下设有几十个分、子公司&#xff0c;我和他曾经在一家子公司——科研分公司。现在的科研分公司解散…

利用Vue2实现印章徽章组件

需要实现的组件效果&#xff1a; 该组件有设置颜色、大小、旋转度数和文本内容功能。 一、组件实现代码 <template><divclass"first-ring"v-bind"getBindValue":class"getStampBadgeClass":style"{ transform: rotate(${rotate}…

前端css介绍

CSS介绍 CSS&#xff08;Cascading Style Sheet&#xff0c;层叠样式表)定义如何显示HTML元素。 当浏览器读到一个样式表&#xff0c;它就会按照这个样式表来对文档进行格式化&#xff08;渲染&#xff09;。 CSS语法 CSS实例 每个CSS样式由两个组成部分&#xff1a;选择器和…

基于springboot实现游戏分享网站系统项目【项目源码+论文说明】

基于springboot实现游戏分享网站演示 摘要 网络的广泛应用给生活带来了十分的便利。所以把游戏分享管理与现在网络相结合&#xff0c;利用java技术建设游戏分享网站&#xff0c;实现游戏分享的信息化。则对于进一步提高游戏分享管理发展&#xff0c;丰富游戏分享管理经验能起到…

超高真空变温台的真空压力和气氛精密控制解决方案

摘要&#xff1a;针对目前国内外显微镜探针冷热台普遍缺乏真空压力和气氛环境精密控制装置这一问题&#xff0c;本文提出了解决方案。解决方案采用了电动针阀快速调节进气和排气流量的动态平衡法实现0.1~1000Torr范围的真空压力精密控制&#xff0c;采用了气体质量流量计实现多…

centos关闭Java进程的脚本

centos关闭Java进程的脚本&#xff0c;有时候服务就是个jar包&#xff0c;关闭程序又要找到进程ID&#xff0c;在kill掉&#xff0c;麻烦&#xff0c;这里就写了个脚本 小白教程&#xff0c;一看就会&#xff0c;一做就成。 1.脚本如下 #!/bin/bash ps -ef | grep java | gre…

Midjourney干货篇 - 与AI对话,如何写好prompt

文章目录 1、语法2、单词3、要学习prompt 框架4、善用参数&#xff08;注意版本&#xff09;5、善用模版6、临摹7、垫图 木匠不会因为电动工具的出现而被淘汰&#xff0c;反而善用工具的木匠&#xff0c;收入更高了。 想要驾驭好Midjourney&#xff0c;可以从以下方面出发调整&…

基于springboot实现原创歌曲分享平台系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现原创歌曲分享平台演示 摘要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理平台应运而生&am…