java基础

java基础

基本数据类型

类型类型名称-字节范围作为成员变量时默认值

整型

字节byte1-128~1270
短整型short2-2^15~2^15-10
整型int4-2^31~2^31-10
长整型long8-2^63~2^63-10L
浮点型浮点型(单精度)float4-3.4×10^38~3.4×10^38(有效位数7)0.0F
浮点型(双精度)double8-1.7×10^308~1.7×10^308(有效位数15)0.0D
字符型字符型char20-65535'\u0000'
布尔型布尔型boolean1true/falsefalse

访问修饰符

  • private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部 类)
  • default (即缺省,什么也不写,不使用任何关键字): 在同一包内可见,不使用 任何修饰符。使用 对象:类、接口、变量、方法。
  • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意: 不能修饰类(外部 类)。
  • public : 对所有类可见。使用对象:类、接口、变量、方法

final finally finalize区别

final可以修饰类、变量、方法,

final

修饰类表示该类不能被继承、

修饰方法表示该方法不能被重写

修饰变量表示该变量是一个常量不能被重新赋值。

finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。

finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调用,当我们调用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的最后判断。

finally 和return 一起时先执行finally。

static

静态只能访问静态。 2、非静态既可以访问非静态的,也可以访问静态的。

1、被static修饰的变量或者方法是独立于该类的任何对象,也就是说,这些变量和方法不属于任何一个 实例对象,而是被类的实例对象所共享。 

2、在该类被第一次加载的时候,就会去加载被static修饰的部分,而且只在类第一次使用时加载并进行初始化,注意这是第一次用就要初始化,后面根据需要是可以再次赋值的。

3、static变量值在类加载的时候分配空间,以后创建类对象的时候不会重新分配。赋值的话,是可以任意赋值的!

4、被static修饰的变量或者方法是优先于对象存在的,也就是说当一个类加载完毕之后,即便没有创建 对象,也可以去访问。

this/super关键字

this

this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指 针。 this的用法在java中大体可以分为3种:

1.普通的直接引用,this相当于是指向当前对象本身。

2.形参与成员名字重名,用this来区分

public Person(String name, int age) {
  this.name = name;
  this.age = age;
}

3.引用本类的构造函数 

class Person{
  private String name;
  private int age;
 
  public Person() {}

  public Person(String name) {
    this.name = name;
  }
  public Person(String name, int age) {
   this(name);
   this.age = age;
  }
}

super

super可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离 自己最近的一个父类。 super三种用法:

1.普通的直接引用 与this类似,super相当于是指向当前对象的父类的引用,这样就可以用 super.xxx来引用父类的成员。

2.子类中的成员变量或方法与父类中的成员变量或方法同名时,用super进行区 分

3.引用父类构造函数

super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句)。

this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)

this与super的区别

  • super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函 数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)
  • this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的 形参与类中的成员数据同名,这时需用this来指明成员变量名)
  • super()和this()类似,区别是,
  • super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法。
  • super()和this()均需放在构造方法内第一行。
  • 尽管可以用this调用一个构造器,但却不能调用两个。
  • this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
  • this()和super()都指的是对象,所以,均不可以在static环境中使用。包括: static变量,static方法,static语句块。
  • 从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字

面向对象特性

Java 面向对象编程三大特性:封装 继承 多态

封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和 安全性。

继承:继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承可以提高代码复用性。继承是多态的前提。 

1. 子类拥有父类非 private 的属性和方法。

2. 子类可以拥有自己属性和方法,即子类可以对父类进行扩展。

3. 子类可以用自己的方式实现父类的方法。

多态性:父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。提高了程序的拓展性

面向对象五大基本原则

  • 单一职责原则SRP(Single Responsibility Principle)类的功能要单一。
  • 开放封闭原则OCP(Open-Close Principle) 一个模块对于拓展是开放的,对于修改是封闭的。
  • 里式替换原则LSP(the Liskov Substitution Principle LSP)子类可以替换父类出现在父类能够出现的任何地方。
  • 依赖倒置原则DIP(the Dependency Inversion Principle DIP)高层次的模块不应该依赖于低层次的 模块,他们都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。
  • 接口分离原则ISP(the Interface Segregation Principle ISP) 设计时采用多个与特定客户类有关的接口比采用一个通用的接口要好。

抽象类和接口

抽象类是用来捕捉子类的通用特性的。接口是抽象方法的集合。 从设计层面来说,抽象类是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。

相同点

  • 接口和抽象类都不能实例化
  • 都位于继承的顶端,用于被其他实现或继承
  • 都包含抽象方法,其子类都必须覆写这些抽象方法

不同点

  • 声明:抽象类使用abstract关键字声明,接口使用interface关键字声明
  • 实现:抽象类子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现,接口子类使用implements关键字来实现接口。它需要提供接口中所有声明的方法的实现。
  • 构造器:抽象类可以有构造器,接口不能有构造器
  • 访问修饰符:抽象类中的方法可以是任意访问修饰符;接口方法默认修饰符是public。并且 不允许定义为 private 或者 protected(default可以写出来,但是编译之后自动转为了public)
  • 多继承:一个类最多只能继承一个抽象类;一个类可以实现多个接口
  • 字段声明:抽象类的字段声明可以是任意的;接口的字段默认都是 static 和 final 的

普通类不能包含抽象方法,抽象类可以包含抽象方法。抽象类不能直接实例化,普通类可以直接实例化。

abstract 可以修饰类、接口、方法

成员变量与局部变量的区别

变量:在程序执行的过程中,在某个范围内其值可以发生改变的量。从本质上讲,变量其实是内存中的一小块区域

成员变量:方法外部,类内部定义的变量

局部变量:类的方法中的变量。

成员变量和局部变量的区别

作用域

        成员变量:针对整个类有效。

        局部变量:只在某个范围内有效。(一般指的就是方法,语句体内)

存储位置

        成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。

        局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。当方法调用完,或者语句结束后,就自动释放。

生命周期

        成员变量:随着对象的创建而存在,随着对象的消失而消失

        局部变量:当方法调用完,或者语句结束后,就自动释放。

初始值

        成员变量:有默认初始值。

        局部变量:没有默认初始值,使用前必须赋值。

使用原则

        在使用变量时需要遵循的原则为:就近原则首先在局部范围找,有就使用;接着在成员位置找

内部类

内部类可以分为四种:成员内部类、局部内部类、匿名内部类和静态内部类。

待补充

重写与重载

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。

重载:发生在同一个类中,方法名相同参数列表不同(参数类型不同、个数不同、顺序不同),与方法返回值和访问修饰符无关,即重载的方法不能根据返回类型进行区分

重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于父 类,访问修饰符大于等于父类(里氏代换原则);如果父类方法访问修饰符为private则子类中就不是重写。

JavaScript七种数据类型

在 JavaScript 规范中,共定义了七种数据类型,分为 “基本类型” 和 “引用类型” 两大类,如下所示:

  • 基本类型:String、Number、Boolean、Symbol、Undefined、Null 
  • 引用类型:Object

servlet 与CGI区别

servlet 被服务器实例化后,容器运行init方法,请求到达时运行service方法,service方法自动派遣运行与请求对应的doGet,doPost方法,当服务器销毁实例时调用destory方法

servlet处于服务器进程中,通过多线程方式运行service方法,一个实例可服务于多个请求,实例一般不会销毁。

cgi对每个请求都会产生新的进程,服务完后就销毁,效率低

常量池

每个class一份,存在于字节码文件中。常量池中有字面量(数量值、字符串值)和符号引用(类符号引用、字段符号引用、方法符号引用),虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等类型

运行时常量池

每个class一份,存在于方法区中(元空间)。当类加载到内存中后,jvm就会将class常量池中的内容存放到运行时常量池中,经过解析(resolve)之后,也就是把符号引用替换为直接引用,解析的过程会去查询全局字符串池,也就是下面的StringTable,以保证运行时常量池所引用的字符串与全局字符串池中所引用的是一致的。

字符串常量池

每个JVM中只有一份,存在于方法区中(堆)。全局字符串池里的内容是在类加载完成,经过验证,准备阶段之后在堆中生成字符串对象实例,然后将该字符串对象实例的引用值存到string pool中(string pool中存的是引用值而不是具体的实例对象,具体的实例对象是在堆中开辟的一块空间存放的)。 在HotSpot VM里实现的string pool功能的是一个StringTable类,它是一个哈希表,里面存的是驻留字符串(用双引号括起来的引用而不是驻留字符串实例本身),也就是说在堆中的某些字符串实例被这个StringTable引用之后就等同被赋予了”驻留字符串”的身份。

String和StringBuffer、StringBuilder的区别是什么?

可见性

String类中使用字符数组保存字符串,private final char value[],所以 string对象是不可变的。StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,char[] value,这两种对象都是可变的。

线程安全性

String中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。

StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。

StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。

性能

每次对String 类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String 对象。StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StirngBuilder 相比使用StringBuffer 仅能获得10%~15% 左右的性能提升,但却要冒多线程不安全的风险。

对于三者使用的总结

如果要操作少量的数据用  String

单线程操作字符串缓冲区 下操作大量数据  StringBuilder

多线程操作字符串缓冲区 下操作大量数据  StringBuffer

包装类

自动装箱与拆箱

装箱:将基本类型用它们对应的引用类型包装起来;

拆箱:将包装类型转换为基本数据类型;

int 和 Integer 有什么区别

Java 是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java 为每一个基本数据类型都引入了对应的包装类型(wrapperclass),int 的包装类就是 Integer,从 Java 5 开始引入了自动装箱/拆箱机制,使得二者可以相互转换。

Integer a = 100, b = 100, c = 150, d = 150;

System.out.println(a == b);// true

System.out.println(c == d);// false

因为Integer缓存了 -128 到 127 之间的数值,可通过设置修改范围。Long同样做了缓存 通过源码可以看出,如果用 Integer.valueOf(int) 来创建整数对象, 参数大于等于整数缓存的最小值( IntegerCache.low )并小于等于整数缓存的 最大值( IntegerCache.high), 会直接从缓存数组 (java.lang.Integer.IntegerCache#cache) 中提取整数对象; 否则会 new 一个整数对象

其他

switch 是否能作用在 byte 上,是否能作用在 long 上,是否 能作用在 String 上

在 Java 5 以前,switch(expr)中,expr 只能是 byte、short、char、int。从 Java5 开始,Java 中引入 了枚举类型,expr 也可以是 enum 类型,从 Java 7 开始,expr 还可以是字符串(String),但是长整 型(long)在目前所有的版 本中都是不可以的

用最有效率的方法计算 2 乘以 8

2 << 3(左移 3 位相当于乘以 2 的 3 次方,右移 3 位相当于除以 2 的 3 次 方)。 

float f=3.4;是否正确

不正确。3.4 是双精度数,将双精度型(double)赋值给浮点型(float)属于 下转型(down-casting, 也称为窄化)会造成精度损失,因此需要强制类型转 换float f =(float)3.4; 或者写成 float f =3.4F。

short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗

对于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 类型,因此 s1+1 运算结果也是 int型,需要强制转换类型才 能赋值给 short 型。 而 short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于 s1 = (short(s1 + 1);其 中有隐含的强制类型转换

在 Java 中,如何跳出当前的多重嵌套循环

在Java中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使 用带有标号的break 语句,即可跳出外层循环

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

字符型常量和字符串常量的区别

1. 形式上: 字符常量是单引号引起的一个字符 字符串常量是双引号引起的若干个字符

2. 含义上: 字符常量相当于一个整形值(ASCII值),可以参加表达式运算 字符串常量代表一个地址值(该字符串在内存中存放位置)

3. 占内存大小 字符常量只占一个字节 字符串常量占若干个字节(至少一个字符结束标志)

值传递

当一个对象被当作参数传递到一个方法后,此方法可改变这个对 象的属性,并可返回变化后的结果,那么这里到底是值传递还是 引用传递是值传递。Java 语言的方法调用只支持参数的值传递。当一个对象实例作为一 个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被 调用过程中被改变,但对对象引用的改变是不会影响到调用者

值传递和引用传递有什么区别

值传递:指的是在方法调用时,传递的参数是按值的拷贝传递,传递的是值的拷 贝,也就是说传递后就互不相关了。 引用传递:指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引 用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,也就是说 传递前和传递后都指向同一个引用(也就是同一个内存空间)。

double 精度丢失

浮点数由两部分组成:指数和尾数,

计算机采用二进制计算和储存,所以在计算机计算和储存数据时会将十进制的数转化为二进制的数,部分数字在十进制转化为二进制时会产生无限小数,,由于double类型的储存空间有限,就会造成精度损失

double d=2.4d 是十进制的,但计算机不能直接识别,要先编译成二进制

long类型的变量赋值时,所赋值的后面要加上字母L(或l)。如果赋的值未超过int类型的取值范围,则可以省略字母。

long num=2200000000L;//所赋的值超出int类型的取值范围,后面加L

long num=198L; //未超出,后面可以加L

long num=198; //未超出,后面可省略L

小数会被默认为double类型的值,因此在为一个float类型的变量赋值时,在所赋值的后 面一定要加上字母F(或者小写字母f),而为double类型的变量赋值时,可以在所赋值的后面加上字母D(或小写字母d),也可以不加

float f=123.4f;//为float类型的变量赋值,后面必须加上字母f

double d1=100.1;//为double类型的变量赋值,后面可以省略字母d

double d2=199.3d;//为double类型的变量赋值,后面可以加字母d

在程序中也可以为一个浮点数类型变量赋予一个整数数值。

float f=100;//声明一个float类型的变量并赋整数值

double d=100;//声明一个double类型的变量并赋整数值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值