JDK源码之基础类

一 概述

1、Java,是一套语言规范,例如规定了变量如何定义、控制语句如何写等,提供基本的语法规范。JDK是java自带的一套调用组件,是对基本java语法规范的进一步封装,jdk中都是使用java基本的语法来写的,使用JDK能够更好的使用java。

2、在整个JDK API中,大约包含1200个包,包名主要有三种:java、javax和org其中以java开头的包名是JDK的基础语言包,以javax开头的属于JDK扩展包(其中x是extend的简写),而以org开头的则是第三方组织提供的功能包(org是organization的简写)。而在JDK API中还包含了一些以com.sun开头的包名,这些是SUN公司提供的一些功能包,由于这些包中的类随着JDK版本的更改变化很大,不具备兼容性,所以未在标准的JDK API文档中进行公开。

3、rt.jar文件是java运行时类库,是我们用到最多的基础类库,包括java.lang,java.io,java.net,java.util等。

    java.lang:Java语言包,这个包下的文件不需要显式import。包括:Object类,数据类型相关的类(String,Long,Byte),Class类,线程相关类Thread,异常类Throwable,等。

    java.io:I/O操作相关的类。包括:文件类File,FileReader,FileWriter,输入输出流InputStream/OutputStream,等。

    java.net:网络相关类。包括:http连接类HttpURLConnection,socket类,等。

    java.util:工具类。包括:数据结构相关的类ArrayList、Hashmap,日期类Date,随机数类Random,等。

4、java native方法:不由java实现的方法,一般这些方法都是很底层,跟平台结合紧密,或者使用java实现性能很差。

二 Object

1、Object类是java中所有类的父类,所有类默认继承Object。这也就意味着,Object类中的所有公有方法也将被任何类所继承。如果,整个java类体系是一颗树,那么Object类毫无疑问就是整棵树的根。

  Object类中的方法如下:

  

2.equals()方法:判断指定的对象和传入的对象是否相等。 ”==“和equals()两者比较,前者比较的地址是否相等(常量比值),即是否同一个对象,后者比较的是值是否相等


三 Class

1、先复习几个概念:

    类:事物特征的抽象,可以理解为模板,是事物特征的定义。可以创建对象。

    对象:是一个具体的事物实体,由类创建的。

2、Class类也是一个抽象的事物定义,也是类的一种,同String类以及自己定义的类是一样的。只是名字和class关键字高度相似。Java是大小写敏感的语言。

3、Class类的对象不能像普通类一样,以 new shapes() 的方式创建,Class类的对象只能由JVM创建,因为这个类没有public构造函数。

4、一个类的多个对象只会有一个Class对象。每个类都有一个Class对象

5、基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。 
6、每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。

7、使用Class.forName(),加载一个类到内存中,使用newInstance()创建类。newInstance()方法调用默认构造器(无参数构造器)初始化新建对象。

8、java里面任何类都要装载在虚拟机上才能运行。forName就是装载类用的(new是根据加载到内存中的类创建一个实例,要分清楚)。 至于什么时候用,可以考虑一下这个问题,给你一个字符串变量,它代表一个类的包名和类名,你怎么实例化它?A a = (A)Class.forName("pacage.A").newInstance();这和A a = new A();是一样的效果。

9、jvm在装载类时会执行类的静态代码段,要记住静态代码是和类绑定的,类装载成功就表示执行了你的静态代码了,而且以后不会再执行这段静态代码了。  

10、从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载。但是使用newInstance()方法的时候,就必须保证:这个类已经加载和这个类已经连接了。而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载 java API的那个加载器。现在可以看出,newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。这样分步的好处是显而易见的。我们可以在调用类的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。  

11、用最简单的描述来区分new关键字和newInstance()方法的区别:
  newInstance: 弱类型。低效率。只能调用无参构造。  
  new: 强类型。相对高效。能调用任何public构造。

public class People {
 
  private String name;
  private int age;
  private String gender;
 
  public String getName() {
    return name;
  }
 
  public void setName(String name) {
    this.name = name;
  }
 
  public int getAge() {
    return age;
  }
 
  public void setAge(int age) {
    this.age = age;
  }
 
  public String getGender() {
    return gender;
  }
 
  public void setGender(String gender) {
    this.gender = gender;
  }
 
  public void say() {
    System.out.println("Hello world!");
  }
 
  public String showInfo() {
    return "My name is " + this.name;
  }
 
}
 
public class ClassTest {
 
  public static void main(String[] args) {
    try {
      //先加载类,再创建实例,等同于People tim = new People();
      People tim = (People) Class.forName("com.tim.People").newInstance();
      tim.say();
 
      // 获取tim这个对象的类描述信息,
      // 可以获取:类的构造方法,已经声明的字段、方法,获取类或者方法的注解,获取类的包名、父类,以及判断类是否是数组、是否是枚举、是否是接口
      // 主要针对不清楚类的内部信息时,使用该方法获取
      Class peopleClass = tim.getClass();
      Field[] peopleField = peopleClass.getDeclaredFields();//获取类的字段
      for (Field field : peopleField) {
        System.out.println(field.getName());
      }
 
    } catch (InstantiationException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }
 
}

四 字符串类

1.String类(字符串常量)→subString是截取字符串的方法。length是字符串长度的方法。int compare(String s)是比较两个字符串的大小,相等返回0,不相等返回不相等字符编码值的差。 
2.StringBuffer类(字符串可以改变,线程安全)→append(String str)在字符串末尾追加一个字符串。char charAt(int index)返回指定下标的字符。intcapacity()表示返回字符串缓冲区容量。 
3.StringBuilder类(字符串可以改变,线程不安全,因此性能比 StringBuffer 好) 
要点:StringBuffer是线程同步的,StringBuilder是异步;对不经常变化的字符串使用String即可。经常变化、正在拼装的字符串不用String。若是全局变量,可能多线程引用,使用StringBuffer;若是局部变量,单线程使用,推荐StringBuilder。 (了解同步和异步就能理解他们的线程区别)
 

五 拆箱装箱

java语言认为一切皆对象。 8个基本数据类型野应该具备对应的对象。 通过封装类可以把8个基本类型的值封装对象进行使用。 从JDK1.5开始,java允许把基本类型的值直接赋值给对应的封装类对象。 
装箱和拆箱 →本质是基本类型和其封装类之间能自动进行转换 
定义:装箱指的是把基本数据类型值转换成封装对象,即把栈中的数据封装成对象存放到堆中的过程。拆箱是装箱的反过程。装箱操作是数据由栈道堆,拆箱是数据由堆到栈。

 //首先要明确一点,对象之间的==是比较内存地址,常数之间的比较是数值比较。
  public static void main(String[] args) {
        Integer num1 = new Integer(100);
        Integer num2 = new Integer(100);
        System.out.println(num1 == num2);//false,因为这两个对象是独立创建的,有自己的内存空间和地址。
        Integer num3 = 100;
        Integer num4 = 100;
        System.out.println(num3 == num4);//true,常数之间比较数值。
        Integer num5 = 128;
        Integer num6 = 128;
        System.out.println(num5 == num6);//false,自动装箱成对象,但是超过了默认的缓存范围,同第一个。如果是127就是true。
        Integer num7 = 100;
        Integer num8 = new Integer(100);
        System.out.println(num7 == num8);//false,两个对象之间比较内存地址,不同的是num7通过自动装箱调用valueOf方法,指向缓存的100,而num8是指向自己内存空间里的100.
        int num9 = 1000;
        Integer num10 = new Integer(1000);
     System.out.println(num9 == num10);//true,Integer对象和int比较时(其它7种也一样),Integer会自动拆箱(intValue方法)成为int,变成两个数值比较。
        Integer num11 = 100;
        System.out.println(num9 == num11);//true,num11通过自动装箱调用valueOf方法指向缓存中的100,比较的时候缓存中的100对象自动拆箱成为数值100.

    //特别的Double,Float是没有缓存机制的,因为即使是-128~127之间的浮点数接近无穷大。
     Float f1 = 1f;
     Float f2 = 1f;
     System.out.print(f1==f2);//false
     //但Double,Float仍然满足拆箱装箱机制(一共8种)。即Double、Float对象与double、float比较时,会自动拆箱成为基础类型,变成两个数值的比较
     float f3 = 1000.0f;
     Float f4 = new Float(1000.0f);
     System.out.print(f3==f4);//true
    }



 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值