• Java基础类库


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

    1. 类的语法定义
      • 类的修饰符
        • 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){}`
        - 方法重载
        同一个类相同方法名,参数列表不同即为重载,和其他项无关。
    
    1. 类的作用
      • 定义变量
      • 创建类的对象
      • 调用类的方法或访问类的变量
    2. this引用
      this关键字总是指向调用该方法的对象。
      • 构造器中引用正在初始化的对象
    public Person(int age){
        this.age = age;
    }
    
    - 普通方法中引用调用该方法的对象(可省略this关键字)
        谁调用set()方法,this代表谁。
    
    public void get(){
    }
        pubilc void set(){
            this.get();
        }
    
    - static修饰的方法不能使用this引用,因为如果使用this,则this无法指向合适的对象
    

    抽象类

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

    1. 抽象方法只有方法签名,没有方法实现。有抽象方法的类只能被定义为抽象类,而抽象类里可以没有抽象方法。抽象类和抽象方法都用abstract修饰。抽象方法和空方法不同。
      public abstract void test();
    2. 抽象类的构造器不能创建实例,仅用于子类调用,子类必须重写抽象方法。所以final、private和abstract不能同时使用,static和abstract不能同时修饰方法,可同时修饰内部类。

    接口

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

    1. 接口使用interface关键字定义。
    2. 接口只能继承接口,可以有多个父接口。
    3. 接口只能包含静态常量(pubilc static final修饰+指定默认值),只能有抽象方法(默认public abstract,普通方法不能有方法实现,类方法和默认方法必须实现),只能定义内部类/接口/枚举(默认public static)。
    4. 访问控制符只能使用public或者省略。
    5. 一个类可以实现多个接口,关键字用implements,放在extends后面。
    6. 实现类必须重写接口所有的抽象方法,必须用public修饰。

    比较抽象类和接口

    Java8增强的包装类

    1. 为了将八种基本数据类型变成引用类型,继承Object类,Java提供了包装类,对应关系如下:
      • byte - Byte
      • short - Short
      • int - Integer
      • long - Long
      • char - Character
      • float - Float
      • double - Double
      • boolean - Boolean
    2. 自动装箱和自动拆箱
      可以直接将一个基本类型的变量赋值给对应的包装类变量,或者赋值给Object变量,自动拆箱则相反。
    3. 字符串转换成基本类型的值
      • 利用除Character类的包装类提供的静态方法
        int it1 = Integer.parseInt("12345");
      • 利用包装类提供的构造器
        float ft1 = new Float("12345");
    4. 基本类型的值转换成字符串
      • 利用连接符+
        String str1 = 10 + "";
      • 利用String类重载的valueOf()方法
        String str2 = String.valueOf(true);
    5. 包装类的实例可以与基本数据类型的值进行比较
    6. 自动装箱缓存问题(见java.lang.Integer类的源代码)
      将-128~127之间的整数自动装箱成Integer实例时,永远都是引用cache数组中的同一个数组元素,而在范围之外的值自动装箱时,总是会创建新的Integer实例,不相同。

    Object类

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

    1. 重写toSpring()方法输出类的对象的状态信息
      public String toString(){
              return "success";
      }
      
    2. ==和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类

    1. String类是不可变类,所以会额外产生很多临时变量
      • int length()方法返回字符串长度
      • charAt(int index)方法返回指定位置的字符
      • int compareTo(String str)方法比较两个字符串的大小,返回长度差或第一个不相同字符的差
      • boolean contentEquals()方法比较两个字符串是否相同
      • byte[] getBytes()方法将字符串转换成数组
      • 。。。
    2. StringBuffer类和StringBuilder类相似,其对象字符串序列可变,前者线程安全,后者性能略高
      • append(String string)方法追加字符串
      • insert(int index, String string)方法插入字符串
      • reverse()方法反转字符串
      • setCharAt()方法
      • setlength()方法设置长度
      • replace(left, right, string)替换字符串
      • toString()方法将StringBuffer对象转换为String对象
    3. 几个面试题
      • 请问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
      
      • 字符串对象一旦被创建就不能被改变。
        指的是字符串常量值不改变。
    4. 正则表达式



    Math类

    其构造器为private修饰,提供大量类变量(如PI、E)和类方法。
    - pow()方法计算乘方
    - random()方法返回一个伪随机数(0.0-1.0)

    Random类和ThreadLocalRandom类

    1. Random类生成的是一种伪随机数,相同的种子相同的方法会产生相同的随机数,因此使用当前时间作种子
      Random rand = new Random(System.currentTimemillis());
    2. 使用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类

    1. 抽象类,调用getInstance()静态方法获取对象。
      Calendar cal = Calendar.getInstance();
      • 获取日期cal.getTime()
      • 修改日历指定字段的值cal.set(2013, 12, 20, 06, 30, 42)
      • add()
      • roll()
    2. 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

    1. final修饰的变量不可被改变,但是final修饰的引用变量所引用的对象的内容可以被改变。final修饰的成员变量必须显式的指定初始值(否则没意义,默认初始化)。
    2. final定义并指定初始值的变量在编译阶段就确定下来,保存在常量池中,程序执行时直接进行宏替换。
    3. final修饰的方法不能被重写,比如Object类中的getClass()方法,
    4. final修饰的类不能被继承。

    不可变类

    1. Java提供的八个包装类和java.lang.String类是不可变类,它们的实例变量不可改变。
    2. 自定义不可变类需要满足的规则:
      • 使用private和final修饰成员变量
      • 使用带参数的构造器来初始化成员变量
      • 提供getter方法,不能提供setter方法
      • 有必要的话重写Object类的hashCode()和equals方法
      • 保证成员变量引用的对象不可变
    3. 如果某个不可变实例经常被使用,需考虑对不可变实例进行缓存,减少系统开销。

    System类和Runtime类

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

    • System类代表当前Java程序的运行平台,它提供了一些代表标准输入、标准输出、错误输出的类变量和用于访问环境变量、系统属性的类方法。
      比如用long Tnow = System.currentTimeMillis()返回系统当前时间。
    • Runtime类代表Java程序的运行时环境,可以访问JVM的相关信息。

    内部类

    Java8新增的lambda表达式

    参见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;
    		
    		}
    	}
    }
    
  • 相关阅读:
    【三】shiro入门 之 Realm
    【一】shiro入门 之 Shiro简介
    【二】shiro入门 之 身份验证
    [01] radio ,checkbox 表单文字对齐
    [02]时区时间获取
    【14】redux 之 redux-actions
    【02】webpack 之 入门
    【13】react 之 redux(2)
    【12】react 之 redux(1)
    【11】react 之 flux
  • 原文地址:https://www.cnblogs.com/pycrab/p/8735154.html
Copyright © 2020-2023  润新知