JAVA复习总结(一)

本文是Java复习总结的第一部分,主要介绍了Java的特点,包括其跨平台能力、面向对象编程和字节码运行机制。详细讲解了JDK的编译与运行过程,以及Java编码规范。还探讨了类的命名规则、基本数据类型、自定义函数和构造函数的概念。此外,讨论了继承、抽象类和接口的使用,以及多态和静态关键字的作用。最后提到了单例模式、不可变对象和字符串操作的相关知识。
摘要由CSDN通过智能技术生成

Java特点:

  • 一次编写,到处运行,兼容各种不同体系结构的CPU、操作系统
  • Java是一种面向对象的语言
    • 将源代码编译成字节码(bytecode,中间态)
    • 然后依赖各种不同平台上的虚拟机来解释执行字节码
    • 新的语言特性能够接纳、兼容和运行其他程序语言产生的字节码

JDK(Java Development Kit)

  • 编译:利用JDK中的javac.exe,将.java文件(代码文件)编译成.class文件(字节码文件)
  • 运行:基于JRE中的java.exe读入并解释.class文件,最终在JVM上运行

Java组件的关系(Eclipse IDE和Java(JDK、JRE、JVM)的关系)
在这里插入图片描述

程序编写遵循的基本编码标准

  • 类名首字母大写,后面单词驼峰命名
  • 方法名和变量名首字母小写,后面单词驼峰命名

Class类

  • Java文件必须以.java作为扩展名
  • 一个Java文件只能有一个public class(其名字必须和文件名字一样,大小写都要完全一致)
  • 一个文件可以有多个class,但只能有一个是public,不提倡一个文件里面放多个类(内部类除外)

基本数据类型

  • boolean:只有true和false两种取值,默认false
  • byte:1byte=8bits,(-128~127),默认值0
  • short:16位,(-32768 ~32767 ,-2^15~ 2 ^15-1),默认值0( 注意: 在对变量赋值的时候不能超过变量数据类型的取值范围,不然会报错
  • int:32位(-2147483648~ 2147483647,-2^31~ 2 ^31-1),默认值0
  • long:64位(-9223372036854775808 ~ 9223372036854775807,-2^63~ 2 ^63-1),默认值0L( 注意:对long类型的变量赋值的时候,后面尽量加L。如果不加L,那么默认为是int转换为long,如果该值超过了int的取值范围,也会报错,但加了L就不会
  • float:32位,符合IEEE753标准的浮点数(1.4E-45~ 3.4028235E38),默认值0.0f(注意:赋值后面必须带f,如float f1=1.23f
  • double:64位,符合IEEE753标准的浮点数(4.9E-324d~1.7976931348623157E308d),默认值0.0d(注意:可以省略末尾d
  • char:一个单一的16位Unicode字符,最小值\u0000(0),最大值\uffff(65535),可以存储任何字符,包括中文。

自定义函数

  • 形式:修饰词(public或static) 返回值 函数名 (形参列表){函数体}
  • 同一个类中,函数名称可以相同,即重载函数,但是函数参数的个数或者类型必须有所不同,不能以返回值来区分同名的函数

构造函数

  • Java构造函数的名称必须和类名一样,且没有返回值
  • 如果没有显式定义构造函数,Java编译器自动为该类产生一个空的无形参构造函数,如果有显式的构造函数,编译器就不会产生了
  • 每个子类的构造函数的第一句话都默认调用父类的无参构造函数super(),除非子类的构造函数第一句话是super。super语句必须放在第一条,不能连续出现两条super语句

继承

  • 每个类只能继承一个类
  • 如果不写extends,Java类默认继承java.lang.Object类

抽象类(abstract class)

  • 不能new操作
  • 如果一个类暂时有方法未实现,需要被定义为抽象类
  • 组成:成员变量(个数不限)、具体方法(个数不限)、抽象方法(加abstract关键字,个数不限)
  • 抽象类也是类。一个类继承于抽象类就不能继承于其他的(抽象)类
  • 子类可以继承抽象类,但一定要实现父类们所有abstract方法,如果不能完全实现,那么子类也必须被定义为抽象类
  • 有构造函数
  • 可以有main函数,也能运行
  • 方法可以有private/protected

接口(interface)

  • 不能new操作
  • 如果类的所有方法都没有实现,那么这个类就算是接口
  • 类可以实现(implements)多个接口,继承和实现可以同时
  • 接口可以继承多个接口(注意:是继承,用extends,接口之间用逗号隔开,如public interface Catfamily extends Animal,ClimbTree{ },Animal,ClimbTree都是接口 ),没有实现的方法将叠加
  • 类实现接口,就必须实现所有未实现的方法。如果没有全部实现,那么只能成为一个抽象类
  • 接口里可以定义变量,但是一般是常量
  • 没有构造函数
  • 没有main函数
  • 方法都是public

类转型

  • 变量支持相互转换
  • 类型可以相互转换,但是只限制于有继承关系的类(子类可以转换成父类,而父类不可以转为子类,除非这个父类本身就是从子类转化过来的)

多态

  • 类型转化带来的作用就是多态(以统一的接口来操纵某一类中不同的对象的动态行为)
  • 子类转型为父类后,调用普通方法,依旧是子类的方法
  • 注意重载和重写的区别
  • 子类的方法优先级高于父类

static

  • static关键字可以用在变量、方法、类、匿名方法块
  • static变量只依赖于类存在(通过类即可访问),不依赖于对象实例存在,所有的对象实例,它们的静态成员变量共享存储在一个共同的空间。
  • static方法也可以通过类名直接引用。但是静态方法中,只能使用静态变量,不能使用非静态变量。而且静态方法禁止引用非静态方法。
  • static块只在类第一次被加载时调用,在程序运行期间,这段代码只运行一次
  • 执行顺序:static块>匿名块(用{}括起来的一段代码)>构造函数

单例模式(Singleton)

  • 又名单态模式
  • 限定某个类在整个程序运行过程中,只能保留一个实例对象在内存空间
  • 采用static来共享对象实例
  • 采用private构造函数,防止外界new操作

在这里插入图片描述

final

  • final关键字可以用来修饰类、方法、字段
  • final的类,不能被继承
  • 父类中如果有final的方法,子类中不能改写此方法
  • final变量,基本类型不能修改值。对象类型不能修改指针,但能修改对象内部的值

常量

  • Java没有const关键字
  • 定义常量用public static final
  • 接口内定义的变量默认是常量(自动加上public static final)
  • Java为很多基本类型的包装类/字符串都建立常量池(相同的值只存储一份,节省内存,共享访问)
  • 基本类型的包装类和字符串有两种创建方式
    1、常量式赋值创建,放在栈内存(将被常量化
    2、new对象进行创建,放在堆内存(不会常量化
  • 以下基本类型的包装类会建立常量池
    1、 Boolean:true,false
    2、Character:0~127
    3、Byte、Short、Int、Long:-128~127
    在这里插入图片描述
public class BoxClassTest {
	public static void main(String[] args)
	{
		int i1 = 10;
		Integer i2 = 10;                // 自动装箱
		System.out.println(i1 == i2);   //true
		// 自动拆箱  基本类型和包装类进行比较,包装类自动拆箱
		
		Integer i3 = new Integer(10);
		System.out.println(i1 == i3);  //true
		// 自动拆箱  基本类型和包装类进行比较,包装类自动拆箱
		
		System.out.println(i2 == i3); //false
		// 两个对象比较,比较其地址。 
		// i2是常量,放在栈内存常量池中,i3是new出对象,放在堆内存中
		
		Integer i4 = new Integer(5);
		Integer i5 = new Integer(5);
		System.out.println(i1 == (i4+i5));   //true
		System.out.println(i2 == (i4+i5));   //true
		System.out.println(i3 == (i4+i5));   //true
		// i4+i5 操作将会使得i4,i5自动拆箱为基本类型并运算得到10. 
		// 基础类型10和对象比较, 将会使对象自动拆箱,做基本类型比较
		
		Integer i6 = i4 + i5;  // +操作使得i4,i5自动拆箱,得到10,因此i6 == i2.
		System.out.println(i1 == i6);  //true
		System.out.println(i2 == i6);  //true
		System.out.println(i3 == i6);  //false
	}	
}
  • Java为常量字符串都建立常量池缓存机制
public class StringConstantTest {
	public static void main(String[] args) {
		String s1 = "abc";
		String s2 = "abc";
		String s3 = "ab" + "c"; //都是常量,编译器将优化,下同
		String s4 = "a" + "b" + "c";
		System.out.println(s1 == s2); //true
		System.out.println(s1 == s3); //true
		System.out.println(s1 == s4); //true
	}
}
public class StringNewTest {
	public static void main(String[] args) {
		String s0 = "abcdef";
		String s1 = "abc";
		String s2 = "abc";
		String s3 = new String("abc");
		String s4 = new String("abc");
		System.out.println(s1 == s2); //true 常量池
		System.out.println(s1 == s3); //false 一个栈内存,一个堆内存
		System.out.println(s3 == s4); //false 两个都是堆内存
		System.out.println("=========================");
		
		String s5 = s1 + "def";    //涉及到变量,故编译器不优化
		String s6 = "abc" + "def"; //都是常量 编译器会自动优化成abcdef
		String s7 = "abc" + new String ("def");//涉及到new对象,编译器不优化
		System.out.println(s5 == s6); //false
		System.out.println(s5 == s7); //false
		System.out.println(s6 == s7); //false
		System.out.println(s0 == s6); //true 
		System.out.println("=========================");
	
		String s8 = s3 + "def";//涉及到new对象,编译器不优化
		String s9 = s4 + "def";//涉及到new对象,编译器不优化
		String s10 = s3 + new String("def");//涉及到new对象,编译器不优化
		System.out.println(s8 == s9); //false
		System.out.println(s8 == s10); //false
		System.out.println(s9 == s10); //false
	}
}

不可变对象

  • 一旦创建,这个对象(状态/值)不能被更改了
  • 其内在的成员变量的值就不能修改了
  • 典型的不可变对象
    1、八个基本型别的包装类的对象
    2、String、BigInteger和BigDecimal等的对象
  • 不可变对象,也是传指针(由于不可变,临时变量指向新内存,外部实参的指针不改动)
public class ImmutableObjectTest {
   public static void main(String[] args) {
   	String a = new String("abc");
   	String b = a;//b和a指向同一块内存
   	System.out.println(b);//abc
   	a = "def";//新开一块内存,其值为“def”,a指向这块内存,b指向的内存不变
   	System.out.println(b);//abc
   	a=new String("abc");
   	change(a);
   	System.out.println(a);//abc
   }
   public static void change(String b)
   {
   	b = "def";
   }
}
  • 如何创建不可变对象
    1、immutable对象是不可改变的,有改变,需clone/new一个对象进行修改
    2、所有的属性都是final和private的
    3、不提供set方法
    4、类是final的,或者所有的方法都是final的
  • 优点:只读,线程安全,并发读,提高性能,可以重复使用
  • 缺点:制造垃圾,浪费空间(因为每一次修改指针的值,都是新开一块内存,让指针指向新开的内存,原来的那块内存只能等待垃圾回收)
  • String是不可变对象,但是StringBuffer(同步(只能有一个线程修改),线程安全,修改快速)/StringBuilder(不同步(可以两个线程同时修改),线程不安全,修改更快)类都是可变对象,可以用append方法进行修改
public class ArgumentPassing {
   public static void changeValue(int a)
   {
   	a = 10;
   }
   public static void changeValue(String s1)
   {
   	s1 = "def";
   }
   public static void changeValue(StringBuffer s1)
   {
   	s1.append("def");
   }
   public static void main(String[] args) {
   	int a = 5;        //基本类型
   	String b = "abc"; //不可变对象
   	StringBuffer c = new StringBuffer("abc"); //可变对象
   	changeValue(a);
   	changeValue(b);
   	changeValue(c);
   	System.out.println(a);//5
   	System.out.println(b);//abc
   	System.out.println(c);//abcdef
   }
}

String类

public class StringTest {
   public static void main(String[] args) {
   	String a = "123;456;789;123 ";
   	System.out.println(a.charAt(0)); // 返回第0个元素
   	System.out.println(a.indexOf(";")); // 返回第一个;的位置
   	System.out.println(a.concat(";000")); // 连接一个新字符串并返回,a不变
   	System.out.println(a.contains("000")); // 判断a是否包含000
   	System.out.println(a.endsWith("000")); // 判断a是否以000结尾
   	System.out.println(a.equals("000")); // 判断是否等于000
   	System.out.println(a.equalsIgnoreCase("000"));// 判断在忽略大小写情况下是否等于000
   	System.out.println(a.length()); // 返回a长度
   	System.out.println(a.trim()); // 返回a去除前后空格后的字符串,a不变
   	String[] b = a.split(";"); // 将a字符串按照;分割成数组
   	for (int i = 0; i < b.length; i++) {
   		System.out.println(b[i]);
   	}

   	System.out.println("===================");

   	System.out.println(a.substring(2, 5)); // [2,5) 截取a的第2个到第5个字符 a不变
   	System.out.println(a.replace("1", "a"));
   	System.out.println(a.replaceAll("1", "a")); // replaceAll第一个参数是正则表达式,a不变
   	System.out.println("===================");

   	String s1 = "12345?6789";
   	String s2 = s1.replace("?", "a");
   	String s3 = s1.replaceAll("[?]", "a");
   	// 这里的[?] 才表示字符问号,这样才能正常替换。不然在正则中会有特殊的意义就会报异常
   	System.out.println(s2);
   	System.out.println(s3);
   	System.out.println(s1.replaceAll("[\\d]", "a")); //将s1内所有数字替换为a并输出,s1的值未改变。
   }
}

StringBuffer类

public class StringBufferCapacityTest {
   public static void main(String[] args) {
   	//StringBuffer的的初始大小为(16+初始字符串长度)即capacity=16+初始字符串长度
   	//length 实际长度  capacity 存储空间大小
   	StringBuffer sb1 = new StringBuffer();
   	System.out.println("sb1 length: " + sb1.length());//0
   	System.out.println("sb1 capacity: " + sb1.capacity());//16
   	System.out.println("=====================");
   	
   	StringBuffer sb2 = new StringBuffer("123");
   	sb2.append("456");
   	System.out.println("sb2 length: " + sb2.length());//6
   	System.out.println("sb2 capacity: " + sb2.capacity());//19
   	System.out.println("=====================");
   	
   	sb2.append("7890123456789");
   	System.out.println("sb2 length: " + sb2.length());//19
   	System.out.println("sb2 capacity: " + sb2.capacity());//19
   	System.out.println("=====================");
   	
   	sb2.append("0");
   	System.out.println("sb2 length: " + sb2.length());//20
   	System.out.println("sb2 capacity: " + sb2.capacity());//40
   	//一旦length大于capacity时,capacity便在前一次的基础上加1后翻倍;
   	System.out.println("=====================");
   	
   	//当前sb2length 20   capacity 40, 再append 70个字符 超过(加1再2倍数额)
   	sb2.append("1234567890123456789012345678901234567890123456789012345678901234567890");
   	System.out.println("sb2 length: " + sb2.length());//90
   	System.out.println("sb2 capacity: " + sb2.capacity());//90
   	//如果append的对象很长,超过(加1再2倍数额),将以最新的长度更换
   	
   	System.out.println("=====================");
   	sb2.append("0");
   	System.out.println("sb2 length: " + sb2.length());//91
   	System.out.println("sb2 capacity: " + sb2.capacity());//182
   	sb2.trimToSize();//去除空隙,将字符串存储压缩到实际大小
   	System.out.println("=====after trime================");
   	System.out.println("sb2 length: " + sb2.length());//91
   	System.out.println("sb2 capacity: " + sb2.capacity());//91
   }
}

package

  • 如果所有的Java类都是放置在同一个目录(包)下面,那么类之间的相互调用无需显式声明调用(同一目录下面,两个类的名字不能相同)
  • Java支持多个目录放置Java,并通过package/import/classpath/jar等机制配合使用,可以支持跨目录放置和调用Java类
  • 类的完整的名字:包名+类名
  • 如果使用默认包,那么类文件前面可以不写包名,否则,需要写包名

import

  • import必须放在package之后,类定义之前
  • 可以用*来引入一个目录下的所有类,但不包括该目录下面子目录中的文件
  • 如果被调用的类不在调用类所在的包中,那么需要用import引入
  • 注意:*引入可能出现同名文件

jar

  • jar文件实际上是一组class文件的压缩包
  • jar文件只包括class,而没有java文件
  • 导出的jar文件并不是放在同一个目录下,而是根据导出时文件的相对存放位置存放的,在引用其中的class文件时,只需要import +jar文件中class路径即可,不需要写jar文件的路径和名称了

Java访问权限

  • private:私有的,只能本类访问
  • default:通常不写,同一个包内访问
  • protected:同一个包,不同包的子类能访问(子类继承父类之后,直接使用,而不是在子类中new一个父类,然后通过该对象调用)
  • public:公开的,所有类都可以访问
  • 四种权限都可以修饰成员变量、成员方法、构造函数
  • default和public可以修饰类

Java数字类(java.math包)

  • 整数:Short、Int、Long
  • 浮点数:Float、Double
  • 大数类:BigInteger(支持无限大的整数运算)、BigDecimal(支持无限大的小数运算,注意精度和截断)
import java.math.BigInteger;

public class BigIntegerTest {

   public static void main(String[] args) {
   	BigInteger b1 = new BigInteger("123456789"); // 声明BigInteger对象
   	BigInteger b2 = new BigInteger("987654321"); // 声明BigInteger对象
   	System.out.println("b1: " + b1 +  ", b2:" + b2);
   	System.out.println("加法操作:" + b2.add(b1)); // 加法操作
   	System.out.println("减法操作:" + b2.subtract(b1)); // 减法操作
   	System.out.println("乘法操作:" + b2.multiply(b1)); // 乘法操作
   	System.out.println("除法操作:" + b2.divide(b1)); // 除法操作
   	System.out.println("最大数:" + b2.max(b1)); // 求出最大数
   	System.out.println("最小数:" + b2.min(b1)); // 求出最小数
   	BigInteger result[] = b2.divideAndRemainder(b1); // 求出余数的除法操作
   	System.out.println("商是:" + result[0] + ";余数是:" + result[1]);
   	System.out.println("等价性是:" + b1.equals(b2));
   	int flag = b1.compareTo(b2);
   	if (flag == -1)
   		System.out.println("比较操作: b1<b2");
   	else if (flag == 0)
   		System.out.println("比较操作: b1==b2");
   	else
   		System.out.println("比较操作: b1>b2");
   }
}
import java.math.BigDecimal;
import java.math.BigInteger;

public class BigDecimalTest {
   public static void main(String[] args) {
   	BigDecimal b1 = new BigDecimal("123456789.987654321"); // 声明BigDecimal对象
   	BigDecimal b2 = new BigDecimal("987654321.123456789"); // 声明BigDecimal对象
   	System.out.println("b1: " + b1 +  ", b2:" + b2);
   	System.out.println("加法操作:" + b2.add(b1)); // 加法操作
   	System.out.println("减法操作:" + b2.subtract(b1)); // 减法操作
   	System.out.println("乘法操作:" + b2.multiply(b1)); // 乘法操作
   	//需要指定位数,防止无限循环,或者包含在try-catch中
   	System.out.println("除法操作:" + b2.divide(b1,10,BigDecimal.ROUND_HALF_UP)); // 除法操作,10为保留小数位数,BigDecimal.ROUND_HALF_UP四舍五入
   	
   	System.out.println("最大数:" + b2.max(b1)); // 求出最大数
   	System.out.println("最小数:" + b2.min(b1)); // 求出最小数
   	
   	int flag = b1.compareTo(b2);
   	if (flag == -1)
   		System.out.println("比较操作: b1<b2");
   	else if (flag == 0)
   		System.out.println("比较操作: b1==b2");
   	else
   		System.out.println("比较操作: b1>b2");
   	
   	System.out.println("===================");
   	
   	//尽量采用字符串赋值
   	System.out.println(new BigDecimal("2.3"));//2.3
   	System.out.println(new BigDecimal(2.3));//2.29999999999999982236431605997495353221893310546875
   	System.out.println("===================");
   	BigDecimal num1 = new BigDecimal("10");
   	BigDecimal num2 = new BigDecimal("3");
   	//需要指定位数,防止无限循环,或者包含在try-catch中
   	BigDecimal num3 = num1.divide(num2, 3, BigDecimal.ROUND_HALF_UP);
   	System.out.println(num3);
   }
}
  • 随机数类:Random
    1、nextInt()//返回一个随机int
    2、nextInt(int a)//返回一个[ 0 , a )之间的随机 int
    3、nextDouble()//返回一个[ 0.0 ,1.0 ]之间的double
    4、ints方法批量返回随机数数组
  • Math.random()//返回一个[ 0.0 ,1.0 ]之间的double
  • 工具类:Math
import java.util.Random;

public class RandomTest {

	public static void main(String[] args) 
	{
		//第一种办法,采用Random类 随机生成在int范围内的随机数
		Random rd = new Random();
		System.out.println(rd.nextInt());
		System.out.println(rd.nextInt(100)); //0--100的随机数
		System.out.println(rd.nextLong());
		System.out.println(rd.nextDouble());		
		System.out.println("=========================");
		
		//第二种,生成一个范围内的随机数 例如0到时10之间的随机数
		//Math.random[0,1)
		System.out.println(Math.round(Math.random()*10));
		System.out.println("=========================");
		
		//JDK 8 新增方法
        rd.ints();  //返回无限个int类型范围内的数据
        int[] arr = rd.ints(10).toArray();  //生成10个int范围类的个数。
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        System.out.println("=========================");
		
        arr = rd.ints(5, 10, 100).toArray();//生成5个[10,100)中的数。
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        System.out.println("=========================");
        
        arr = rd.ints(10).limit(5).toArray();//只有5个数
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
	}
}

数字工具类java.lang.Math

public class MathTest {
	public static void main(String[] args) {	
		System.out.println(Math.abs(-5));    //绝对值
		System.out.println(Math.max(-5,-8)); //最大值
		System.out.println(Math.pow(-5,2));  //求幂
		System.out.println(Math.round(3.5)); //四舍五入
		System.out.println(Math.ceil(3.5));  //向上取整
		System.out.println(Math.floor(3.5)); //向下取整
	}
}

不熟悉的点

  • 子类可以继承父类所有内容(不能直接访问private成员,即父类中有一个private成员,子类继承父类之后,字类的对象不能调用和使用该private成员)
  • (A obj=new A(),obj相当于一个指针,java中叫作reference)
  • 类中的属性是有默认初值的,但是方法中定义的变量没有,需要进行初始化,不然会报错
  • this还能代替本类的构造函数,可以用在一个构造函数里面调用另一个构造函数的时候,如this(5)//调用本类的一个形参的构造函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值