java 类库_Java基础类库

面向对象的核心—类和对象

类的语法定义

类的修饰符

static可以修饰变量和方法,称为类变量、类方法,它们属于类本身。不被static修饰的变量和方法称为实例变量、实例方法,属于类的实例。

在类准备阶段,系统就为类变量分配内存空间,类初始化阶段完成类变量的初始化。类变量可以通过类来访问,也可以通过类的对象来访问(其实系统在底层转换成通过该类访问类变量,并不会为类变量分配内存),类方法也是。

类成员的作用域比实例成员的作用域更大,可能类成员初始化完成而实例成员未初始化完成,为避免错误,类成员不能访问实例成员。

[public/final/abstract] class Name{

//构造器

[public/private/protected] Name(struct val){

}

//成员变量

[public/protected/private/static/final] type tname [= defualt];

//方法

[public/protected/private/static/final/abstract] type set/get(struct val){

}

}

- 类名

- 成员变量

类的成员变量分为类变量和实例变量,类变量与类共存亡,实例变量与对象共存亡。

- 局部变量

局部变量分为形参、方法局部变量和代码块局部变量,除了形参之外的局部变量声明后必须显式初始化才能使用(系统不会默认初始化局部变量)。局部变量保存基本类型的值或者对象的引用,存放在栈内存中,随着方法或代码块的结束而消亡。

- 构造器

- 构造器名与类名相同,不能显式指定返回值(隐式返回当前类)。没有显式提供构造器时调用系统默认构造器,即Java至少有一个构造器。

- 创建对象的根本途径就是使用new关键字调用类的构造器。

`Person p = new Person();`

p是一个引用变量,只存储一个地址值,Java程序不允许直接访问堆内存中的对象,只能通过对象的引用来访问。`创建对象`的过程如下:

- 调用构造器

- 类准备阶段--系统为对象分配内存空间

- 类初始化阶段--执行初始化块,执行默认初始化

- 通过this引用执行构造器内的程序体,进行显式初始化

- 返回该对象

- 构造器重载

如果一个构造器包含另一个构造器,则可以使用this来调用另一个构造器,方便以后的修改,降低维护成本。

- 初始化块

如果多个构造器中有相同的初始化代码,则可以把它们放到普通初始化块里完成。初始化块总在构造器执行之前执行。static{}静态初始化块初始化类。

- 方法

- Java的方法只能属于类本身或者类的对象,不能独立存在。

- Java方法只能使用值传递。如果参数是基本类型的值,则会开辟新的栈内存存放临时变量;如果参数是引用类型的值,也会开辟新的栈内存存放引用变量,但是变量都是指向堆内存的同一对象。

- 参数为数组时可以采用形参个数可变的方法,进而使用foreach循环。

`public void exmple(int a, String... strings){}`

- 方法重载

同一个类相同方法名,参数列表不同即为重载,和其他项无关。

类的作用

定义变量

创建类的对象

调用类的方法或访问类的变量

this引用

this关键字总是指向调用该方法的对象。

构造器中引用正在初始化的对象

public Person(int age){

this.age = age;

}

- 普通方法中引用调用该方法的对象(可省略this关键字)

谁调用set()方法,this代表谁。

public void get(){

}

pubilc void set(){

this.get();

}

- static修饰的方法不能使用this引用,因为如果使用this,则this无法指向合适的对象

抽象类

抽象类作为一种模板,提供通用的方法,是一种更高层次的抽象。

抽象方法只有方法签名,没有方法实现。有抽象方法的类只能被定义为抽象类,而抽象类里可以没有抽象方法。抽象类和抽象方法都用abstract修饰。抽象方法和空方法不同。

public abstract void test();

抽象类的构造器不能创建实例,仅用于子类调用,子类必须重写抽象方法。所以final、private和abstract不能同时使用,static和abstract不能同时修饰方法,可同时修饰内部类。

接口

接口作为特殊的抽象类,是一种规范,其不提供任何方法实现。所有方法都是抽象方法,Java8允许定义默认方法(default修饰,可以提供实现)。

接口使用interface关键字定义。

接口只能继承接口,可以有多个父接口。

接口只能包含静态常量(pubilc static final修饰+指定默认值),只能有抽象方法(默认public abstract,普通方法不能有方法实现,类方法和默认方法必须实现),只能定义内部类/接口/枚举(默认public static)。

访问控制符只能使用public或者省略。

一个类可以实现多个接口,关键字用implements,放在extends后面。

实现类必须重写接口所有的抽象方法,必须用public修饰。

比较抽象类和接口

a585ca47fd7fed351f6f107cb0283788.png

Java8增强的包装类

为了将八种基本数据类型变成引用类型,继承Object类,Java提供了包装类,对应关系如下:

byte - Byte

short - Short

int - Integer

long - Long

char - Character

float - Float

double - Double

boolean - Boolean

自动装箱和自动拆箱

可以直接将一个基本类型的变量赋值给对应的包装类变量,或者赋值给Object变量,自动拆箱则相反。

字符串转换成基本类型的值

利用除Character类的包装类提供的静态方法

int it1 = Integer.parseInt("12345");

利用包装类提供的构造器

float ft1 = new Float("12345");

基本类型的值转换成字符串

利用连接符+

String str1 = 10 + "";

利用String类重载的valueOf()方法

String str2 = String.valueOf(true);

包装类的实例可以与基本数据类型的值进行比较

自动装箱缓存问题(见java.lang.Integer类的源代码)

将-128~127之间的整数自动装箱成Integer实例时,永远都是引用cache数组中的同一个数组元素,而在范围之外的值自动装箱时,总是会创建新的Integer实例,不相同。

Object类

Java所有的类默认继承Object父类,因此所有的类都可调用父类的方法。

重写toSpring()方法输出类的对象的状态信息public String toString(){

return "success";

}

==和equals方法

运算符

如果两个数值类型(不一定数据类型严格对应)相等则返回true;如果两个引用变量指向同一对象则返回true,不能比较非父子关系的两个对象。

关于常量池

在编译时被确定并保存在.class文件中的字符串常量和类、接口、方法中的常量保存在常量池中。常量池中的常量是唯一的。new Integer(12)实际上定义了两个对象。

class EqualTest{

public void compare() {

String str1 = "123";

String str2 = "123";

String str3 = new String("123");

String str4 = new String("123");

System.out.println(str1 == str2);

System.out.println(str1 == str3);

System.out.println(str3 == str4);

System.out.println(str1.equals(str2));

System.out.println(str1.equals(str3));

System.out.println(str3.equals(str4));

}

}

输出true、false、false;true、true、true。

- equals方法

- 如果两个对象的值相等则返回true。

- String已经重写了equals方法,对于其他的Object类equals方法等同于==(都是比较对象的地址),如果想自定义可以重写equals方法。

- equals方法的前一个变量不能为null,如"123".equals(str)

public class Test {

String id = "213";

public String getId() {

return id;

}

public boolean equals(Object object) {

if(this == object)

return true;

if(object != null && object.getClass() == Test.class) {

Test test = (Test)object;

if(this.getId().equals(test.getId())) {

return true;

}

}

return false;

}

}

equals要求两个对象是同一个类的实例,所以用object.getClass()==Test.class代替instanceof,这里用到了反射基础。

3. getClass()方法

返回该对象的运行时类。

4. 控制线程的暂停和运行的方法

wait()、notify()、notifyAll()

5. protected修饰的clone()方法

自定义类实现克隆如下:

//自定义类实现Cloneable接口

public class User implements Cloneable{

//自定义实现clone()方法

public User cloneUser() throws CloneNotSupportedException {

//返回对象的副本

return (User)super.clone();

}

}

使用克隆数组比copy方法快。

Objects工具类

提供空指针安全的方法来操作对象。

String、StringBuffer和StringBuilder类

String类是不可变类,所以会额外产生很多临时变量

int length()方法返回字符串长度

charAt(int index)方法返回指定位置的字符

int compareTo(String str)方法比较两个字符串的大小,返回长度差或第一个不相同字符的差

boolean contentEquals()方法比较两个字符串是否相同

byte[] getBytes()方法将字符串转换成数组

。。。

StringBuffer类和StringBuilder类相似,其对象字符串序列可变,前者线程安全,后者性能略高

append(String string)方法追加字符串

insert(int index, String string)方法插入字符串

reverse()方法反转字符串

setCharAt()方法

setlength()方法设置长度

replace(left, right, string)替换字符串

toString()方法将StringBuffer对象转换为String对象

几个面试题

请问String s = new String("hello");创建了几个对象。

两个。一个"hello"字符串对象,在方法区的常量池;一个s对象,在栈内存。

请写出下面的结果

String s1 = new String("abc");

String s2 = new String("abc");

String s3 = "abc";

String s4 = "abc";

syso(s1==s2); //false

syso(s1==s3); //false

syso(s3==s4); //true

字符串对象一旦被创建就不能被改变。

指的是字符串常量值不改变。

正则表达式

9c169df64eb97d55d4fcbdad78c0eaac.png

2f1dfc5e64e0707f3d9334e1efa0cf00.png

616853a0083fb6653eb7bb86e4558144.png

a569175823b9de8e55607a4902305a86.png

Math类

其构造器为private修饰,提供大量类变量(如PI、E)和类方法。

- pow()方法计算乘方

- random()方法返回一个伪随机数(0.0-1.0)

Random类和ThreadLocalRandom类

Random类生成的是一种伪随机数,相同的种子相同的方法会产生相同的随机数,因此使用当前时间作种子

Random rand = new Random(System.currentTimemillis());

使用ThreadLocalRandom在并发环境下具有更好的线程安全性,它通过current()方法生成对象

ThreadLocalRandom rand = ThreadLocalRandom.current();

- 生成指定范围的随机数

int tmp = rand.nextInt(5, 10);

BigDecimal类

Java的float和double类型会引起精度丢失,BigDecimal类提供大量构造器创建对象。

- 优先推荐使用参数为String的构造器。

- 如果必须使用浮点数为参数的构造器,需要使用valueOf(double val)静态方法转换为BigDecimal对象

BigDecimal f = BigDecimal.valueOf(12.45);

- 基本运算有add()方法、subtract()方法、multiply()方法、divide()方法、pow()方法等

Calendar类

抽象类,调用getInstance()静态方法获取对象。

Calendar cal = Calendar.getInstance();

获取日期cal.getTime()

修改日历指定字段的值cal.set(2013, 12, 20, 06, 30, 42)

add()

roll()

java8新增了java.time包,含如下类:

Clock类可取代System类的currentTimemillis()

LocalDate类不带时区的日期,提供静态now()方法获取当前时刻

LocalTime类不带时区的时间

DayOfWeek枚举类定义了周六到周日

Month枚举类定义了十二个月

单例类

不允许自由创建该类的实例,只允许该类创建一个实例。

public class Singleton {

//需要被static方法访问的缓存变量

private static Singleton singleton = null;

//隐藏构造器

private Singleton() {

}

//暴露的方法,因为调用该方法之前还没有对象,所以要用static修饰

public static Singleton getSingleton() {

if(singleton == null)

singleton = new Singleton();

return singleton;

}

}

final

final修饰的变量不可被改变,但是final修饰的引用变量所引用的对象的内容可以被改变。final修饰的成员变量必须显式的指定初始值(否则没意义,默认初始化)。

final定义并指定初始值的变量在编译阶段就确定下来,保存在常量池中,程序执行时直接进行宏替换。

final修饰的方法不能被重写,比如Object类中的getClass()方法,

final修饰的类不能被继承。

不可变类

Java提供的八个包装类和java.lang.String类是不可变类,它们的实例变量不可改变。

自定义不可变类需要满足的规则:

使用private和final修饰成员变量

使用带参数的构造器来初始化成员变量

提供getter方法,不能提供setter方法

有必要的话重写Object类的hashCode()和equals方法

保证成员变量引用的对象不可变

如果某个不可变实例经常被使用,需考虑对不可变实例进行缓存,减少系统开销。

System类和Runtime类

系统提供System类和Runtime类与程序的运行平台进行交互。

System类代表当前Java程序的运行平台,它提供了一些代表标准输入、标准输出、错误输出的类变量和用于访问环境变量、系统属性的类方法。

比如用long Tnow = System.currentTimeMillis()返回系统当前时间。

Runtime类代表Java程序的运行时环境,可以访问JVM的相关信息。

内部类

Java8新增的lambda表达式

枚举类

枚举类是一种特殊的类,使用enum关键字, 定义如下:

public enum SeasonEnum {

SPRING, SUMMER, FALL, WINTER;

}

使用如下:

public class EnumTest {

public void getEnum() {

//枚举类默认的values()方法返回所有实例

for(SeasonEnum s : SeasonEnum.values()) {

System.out.println(s);

}

}

public void select(SeasonEnum s) {

//swich的控制表达式可以是枚举类型

switch (s) {

//无需添加枚举类限定

case SPRING:

System.out.println("spring");

break;

case SUMMER:

System.out.println("summer");

break;

case FALL:

System.out.println("fall");

break;

case WINTER:

System.out.println("winter");

break;

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值