Java知识点之Java基础

Java语言的特性

1、“一次编译,到处运行”

Java语言它首先将.java的源代码编译成.class的二进制字节码文件,然后依赖各种不同平台上的虚拟机来解释执行字节码。从而实现“一次编译,到处执行”的跨平台特性。Java语言是解释型的,如前所述,Java程序在Java平台上被编译成字节码格式,然后可以在实现这个Java平台的任何系统中运行。在运行时,Java平台中的Java解释器,对这些字节码进行解释执行,执行过程中需要的类在联接阶段被载入到运行环境中。

2、简易性

(1)不支持操作符重载

Java中仅有的两个操作符重载为String的“+”和“+=”
在这里插入图片描述

(2)不支持指针

  1. Java没有显式的使用指针
  2. JVM由C++实现,其操作可能涉及指针操作
  3. JVM调用native方法可能涉及指针操作

(3)不支持类的多继承

接口之间可以多继承

(4)不支持自动强制类型转换

  1. 使用强制类型转换的时候要加上强制类型转换符()
  2. boolean类型较为特殊,编译成字节码时用int或者byte表示;JVM中,0表示false;非0表示true

Java的四大基础特性

1、封装

(1)把对象的属性和行为(方法)结合为一个独立的整体,并尽可能的隐藏对象内部的实现细节
(2)Java中,对于对象的内部属性一般用private来实现隐藏,通过get和set方法对外提供访问接口
(3)封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。

2、继承

(1)子类继承父类的属性和行为,并根据自己的需求扩展出新的属性和行为,提高了代码的可复用性
(2)Java的继承通过extend来实现,实现继承的类称为子类,被继承的类称为父类或基类、超类,子类和父类的关系是一般和特殊的关系,子类扩展父类,可以获得父类的所有的可访问的属性和方法
(3)当子类重写父类方法时,会先运行子类的方法,在子类方法中可以通过super来调用父类的方法
(4)当子类创建时,会先调用父类的构造函数,并且在父类中this代表着当前实例化的对象,例:

//此时在father类中调用this,及代表着实例化的Child
Father father = new Child();

(5)子类继承父类的方法后,子类重写此方法的访问权限不能高于父类,如父类为public,则子类只能为public,若父类为protected,子类可以为protected和public,则可以理解为访问权限private>default>protected>public
(6)继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。

3、多态

(1)指允许不同的对象对同一个消息(函数调用)做出响应,即同一消息可以根据发送对象采用多种不同的行为方式
(2)相同类型的引用变量,调用同一个方法呈现不同的行为特征
(3)具体实现方式为接口实现,继承父类进行方法重写,同一个类中进行方法重载
注:重写是子类对父类允许访问的方法的重新编写,返回值和形参相同,即外壳不变,核心重写,而重载是在同一个类中,方法名相同,形参和返回值可以不同,但形参列表必须唯一,如构造函数
(4)多态性是指允许不同类的对象对同一消息做出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题

4、抽象

(1)父类为子类提供一些属性和方法,子类根据业务需求实现具体的行为
(2)抽象类使用abstract进行修饰,子类必须实现父类的所有抽象方法,除非子类也是抽象类
(3)抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。

Java基础语法

1、请你解释Object若不重写hashCode()的话,hashCode()如何计算出来的?

Object的hashCode()方法是本地方法,也就是用c语言或c++实现的,该方法直接返回对象的内存地址

2、请你解释为什么重写equals还要重写hashcode?

HashMap中,如果要比较key是否相等,要同时使用这两个函数!因为自定义的类的hashcode()方法继承于Object类,其hashcode码为默认的内存地址,这样即便有相同含义的两个对象,比较也是不相等的。HashMap中的比较key是这样的,先求出key的hashcode(),比较其值是否相等,若相等再比较equals(),若相等则认为他们是相等的。若equals()不相等则认为他们不相等。如果只重写hashcode()不重写equals()方法,当比较equals()时只是看他们是否为同一对象(即进行内存地址的比较),所以必定要两个方法一起重写。HashMap用来判断key是否相等的方法,其实是调用了HashSet判断加入元素 是否相等。重载hashCode()是为了对同一个key,能得到相同的Hash Code,这样HashMap就可以定位到我们指定的key上。重载equals()是为了向HashMap表明当前对象和key上所保存的对象是相等的,这样我们才真正地获得了这个key所对应的这个键值对。

3、请你解释什么是值传递和引用传递?

(1)值传递是对基本数据变量而言的,传递的是该变量的一个副本,改变副本不影响原变量
(2)引用传递是对对象型变量而言的,传递的是该对象地址的副本,并不是原对象本身,所以对引用对象进行操作会改变原对象的值
(3)在Java中,只存在值传递。当一个引用对象做为一个方法的形参进行传递时,传递的是该对象的内存地址,内存地址在Java中也是用一个数值进行存放的,对象的内容可以在调用方法中改变,但对象的内存地址是永远都不会改变的

4、请列举你所知道的Object类的方法并简要说明。

在这里插入图片描述

Java对象和类

1、请说明类和对象的区别

(1)类是对某一类事物的描述,是抽象的。而对象是一个实实在在的个体,是类的一个实例
(2)对象是函数、变量的集合体;而类是一组函数和变量的集合体,即类是一组具有相同属性的对象集合体

Java基本数据类型

1、基本数据类型的原始类型和包装类型

原始类型包装类型
booleanBoolean
charCharacter
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble

在这里插入图片描述

2、请你解释为什么会出现4.0-3.6=0.40000001这种现象?

二进制的小数无法精确的表达十进制的小数,计算机在计算十进制的小数的过程中要先转换为二进制进行计算,这个过程中出现了误差

3、请你讲讲一个十进制的数在内存中是怎么存的?

以补码的形式

2、自动装箱和自动拆箱

(1)自动装箱是Java编译器在基本数据类型和对象包装类型之间的一个转化(int–>Integer);反之就是自动拆箱(Integer–>int)
(2)Java为每一个基本数据类型引入了包装类型,从Java 5开始引入了自动装箱/自动拆箱机制,使得两者可以互相转换
在这里插入图片描述

3、其他

(1)基本数据类型和void关键字都有class属性,表示的都是class对象,int.class != Integer.class
(2)具有相同属性类型和维数的数组都共享一个Class对象,Class clz = String[].class

Java变量类型

1、String、StringBuffer与StringBuilder之间区别

(1)三者在执行速度上:StringBuilder > StringBuffer > String
(2)StringBuilder执行速度相对快,但是是线程不安全的;StringBuffer执行速度相对慢,但是是线程安全的。底层实现上,StringBuffer就比StringBuilder多了一个Synchronized关键字
(3)对于String,如果是普通字面上的赋值,那么所存的数据会放入字符串常量池,即下一个字面赋值对象再创建的时候(相同),直接从池中取数据,两个对象指向同一内存地址
在这里插入图片描述

2、请解释一下String为什么不可变?

(1)不可变对象指一个对象的状态在对象被创建之后就不再变化。不可改变的意思就是说:不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。
(2)String 不可变是因为在 JDK 中 String 类被声明为一个 final 类,且类内部的 value 字节数组也是 final 的,只有当字符串是不可变时字符串池才有可能实现,字符串池的实现可以在运行时节约很多 heap 空间,因为不同的字符串变量都指向池中的同一个字符串;如果字符串是可变的则会引起很严重的安全问题,譬如数据库的用户名密码都是以字符串的形式传入来获得数据库的连接,或者在 socket 编程中主机名和端口都是以字符串的形式传入,因为字符串是不可变的,所以它的值是不可改变的,否则黑客们可以钻到空子改变字符串指向的对象的值造成安全漏洞;因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享,这样便不用因为线程安全问题而使用同步,字符串自己便是线程安全的;因为字符串是不可变的所以在它创建的时候 hashcode 就被缓存了,不变性也保证了 hash 码的唯一性,不需要重新计算,这就使得字符串很适合作为 Map 的键,字符串的处理速度要快过其它的键对象,这就是 HashMap 中的键往往都使用字符串的原因。
在这里插入图片描述

Java修饰符

Java的访问控制是停留在编译层的,也就是它不会在.class文件中留下任何的痕迹,只在编译的时候进行访问控制的检查。其实,通过反射的手段,是可以访问任何包下任何类中的成员,例如,访问类的私有成员也是可能的。
区别:
public:可以被所有其他类所访问
private:只能被自己访问和修改
protected:自身、子类及同一个包中类可以访问
default:同一包中的类可以访问,声明时没有加修饰符,认为是friendly。
待写

Java运算符

1、请你说明符号“==”比较的是什么?

== 对比两个对象基于内存引用,如果两个对象指向的是一块内存地址,那么返回true,否则返回false; ==两边都是基本数据类型,就是比较值是否相等

1、请你讲讲&和&&的区别?

(1)&运算符有两种用法:“按位与”和“逻辑与”
(2)&&运算符是“短路与”运算。逻辑与跟短路与的差别是非常巨大的,虽然两者都要求运算符左右两边的值都是布尔值true整个结果才为true。&&之所以称为短路与运算是因为,如果&&运算符左边的表达式为false,右边的表达式会被直接短路掉,不会进行运算

Java循环结构

1、请你说明一下,在Java中如何跳出当前的多重嵌套循环?

(1)在最外层循环前加一个标记A,然后break A,这样就可以跳出循环
(2)Java中支持带标签的break和continue

正常情况:

    public static void main(String[] args) {
        label_out:
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                System.out.print(" " + i + j + " ");
            }
            System.out.println();
        }
    }

结果:
在这里插入图片描述
加break情况:

    public static void main(String[] args) {
        label_out:
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                if (j == 3) {
                    break label_out;
                }
                System.out.print(" " + i + j + " ");
            }
            System.out.println();
        }
    }

结果:
在这里插入图片描述
加continue情况:

    public static void main(String[] args) {
        label_out:
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                if (j == 3) {
                    continue label_out;
                }
                System.out.print(" " + i + j + " ");
            }
            System.out.println();
        }
    }

结果:
在这里插入图片描述

Java异常处理

1、请问运行时异常与受检异常有什么区别?

(1)异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常不会发生。受检异常跟程序的上下文环境有关,即使程序设计无误,仍然可能因使用的问题而引发。Java编译器要求方法必须声明抛出可能发生的受检异常,但是并不要求必须声明抛出未被捕获的运行时异常。
(2)运行时异常可以不进行处理,由虚拟机接管。出现运行时异常之后。系统会将异常一直网上抛,直到处理为止,如果对运行时异常不进行捕获处理,那么会中断当前线程
(3)对于一般异常,程序要求我们必须进行捕获,但是也可以往上抛,但是程序出错的话会直接中断当前线程

Java正则表达式

1、Java中是如何支持正则表达式操作的?

Java中的String类提供了支持正则表达式操作的方法,包括matches(),replaceAll(),replaceFirst(),split()。此外,Java中可以用Pattern表示正则表达式对象,他提供了丰富的api进行各种正则表达式操作

2、请你简单描述一下正则表达式及其用途

在编写处理字符串的程序时,经常会有查找符合某些复杂规则的字符串的需要,正则表达式就是描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。计算机处理的信息更多的不是数值而是字符串,正则表达式就是在进行字符串匹配和处理的时候最为强大的工具。

Java其他

1、请你比较一下Java和JavaSciprt?

(1)JavaScript和Java是两个公司开发的不同产品,两者之间毫无关联
(2)Java是面向对象语言,必须设计对象;而JavaScript是基于对象和事件驱动的脚本语言
(3)Java的源代码再执行之前必须经过编译,而JavaScript不需要编译,直接让浏览器解释执行
(4)Java采用强类型变量检查,即所有变量再编译之前必须声明它的类型;而JavaScript是弱类型的,甚至再使用前不做声明,解释器会自行判断
(5)代码格式不一样

2、System.out.println()

out为System类的一个静态不可变成员,类型为PrintStream,PrintStream类中的println()方法有基本数据类型的重载方法(无short)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值