Java初级基础
第一章
1. 1基础语法
大致与C++基本类似
1.2基本数据类型
Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。
类型 | 字节数 | 默认值 |
---|---|---|
byte | 1 | 0 |
short | 2 | 0 |
int | 4 | 0 |
long | 8 | 0L |
float | 4 | 0.0f |
double | 8 | 0.0d |
char | 2 | “u000” |
boolean | false | |
String | null |
引用类型:引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型。
- 对象、数组都是引用数据类型。
- 所有引用类型的默认值都是null。
- 一个引用变量可以用来引用任何与之兼容的类型。
java中利用final修饰常量
final double PI = 3.1415;
自动类型转换
低---------->高
byte,short,char—> int —> long—> float —> double
- 不能对boolean类型进行类型转换。
- 不能把对象类型转换成不相关类的对象。
- 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
- 转换过程中可能导致溢出或损失精度
自动类型转换
必须满足转换前的数据类型的位数要低于转换后的数据类型
强制类型转换
- 条件是转换的数据类型必须是兼容的。
- 格式
(type) value
1.3修饰符
- default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
- private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
- public : 对所有类可见。使用对象:类、接口、变量、方法
- protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
访问控制和继承
- 父类中声明为 public 的方法在子类中也必须为 public。
- 父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。
- 父类中声明为 private 的方法,不能够被继承。
非访问修饰符
static 修饰符,用来修饰类方法和类变量。
- 静态变量:static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。
- 静态方法:static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。
final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
- 父类中的 final 方法可以被子类继承,但是不能被子类重写。
- final 类不能被继承,没有类能够继承 final 类的任何特性。
abstract 修饰符,用来创建抽象类和抽象方法。
- 抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。
- 一个类不能同时被 abstract 和 final 修饰
- 抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。抽象方法不能被声明成 final 和 static。
synchronized 和 volatile 修饰符,主要用于线程的编程。
- synchronized 关键字声明的方法同一时间只能被一个线程访问。
- 序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。
- volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
1.4运算符
操作符 | 描述 |
---|---|
+ | 加法 - 相加运算符两侧的值 |
- | 减法 - 左操作数减去右操作数 |
* | 乘法 - 相乘操作符两侧的值 |
/ | 除法 - 左操作数除以右操作数 |
% | 取余 - 左操作数除以右操作数的余数 |
++ | 自增: 操作数的值增加1 |
— | 自减: 操作数的值减少1 |
运算符 | 描述 |
---|---|
== | 检查如果两个操作数的值是否相等,如果相等则条件为真。 |
!= | 检查如果两个操作数的值是否相等,如果值不相等则条件为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是那么条件为真。 |
< | 检查左操作数的值是否小于右操作数的值,如果是那么条件为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真。 |
操作符 | 描述 |
---|---|
& | 如果相对应位都是1,则结果为1,否则为0 |
| | 如果相对应位都是 0,则结果为 0,否则为 1 |
^ | 如果相对应位值相同,则结果为0,否则为1 |
〜 | 按位取反运算符翻转操作数的每一位,即0变成1,1变成0。 |
<< | 按位左移运算符。左操作数按位左移右操作数指定的位数。 |
>> | 按位右移运算符。左操作数按位右移右操作数指定的位数。 |
>>> | 按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。 |
操作符 | 描述 |
---|---|
&& | 称为逻辑与运算符。当且仅当两个操作数都为真,条件才为真。 |
| | | 称为逻辑或操作符。如果任何两个操作数任何一个为真,条件为真。 |
! | 称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。 |
1.5循环
基本也就那样
增强for循环(主要用于数组的增强型 for 循环)
for(声明语句 : 表达式)
{
}
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
表达式:表达式是要访问的数组名,或者是返回值为数组的方法。
public class Test {
public static void main(String args[]) {
int [] numbers = {10, 20, 30, 40, 50};
for(int x : numbers ) {
if( x == 30 ) {
break;
}
System.out.print( x );
System.out.print("\n");
}
}
}
1.6条件
反反复复就那样
第二章
2.1 StringBuffer 和 StringBuilder 类
和 String
类不同的是,StringBuffer
和StringBuilder
类的对象能够被多次的修改,并且不产生新的未使用对象。
在使用 StringBuffer
类时,每次都会对StringBuffer
对象本身进行操作,而不是生成新的对象,所以如果需要对字符串进行修改推荐使用 StringBuffer
StringBuilder
类在 Java 5 中被提出,它和 StringBuffer
之间的最大不同在于 StringBuilder
的方法不是线程安全的(不能同步访问)。
2.2 Scanner类
导入import java.util.Scanner
import java.util.Scanner;
public class ScannerDemo {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String str1 = scan.nextLine();
}
}
next()
- 一定要读取到有效字符后才可以结束输入。
- 对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
- 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
- next() 不能得到带有空格的字符串。
nextLine()
- 以Enter为结束符,也就是说
nextLine()
方法返回的是输入回车之前的所有字符。 - 可以获得空白。
2.3 数组
创建数组
int[] arr = new int[10];
int[] arr = {1,2,3,4,5,6};
数组作为函数
public static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
数组作为函数的返回值
public static int[] reverse(int[] list) {
int[] result = new int[list.length];
for (int i = 0, j = result.length - 1; i < list.length; i++, j--) {
result[j] = list[i];
}
return result;
}
多维数组
String str[][] = new String[3][4];
java.util.Arrays
类能方便地操作数组,它提供的所有方法都是静态的
2.4 方法
方法的重载
解决方法是创建另一个有相同名字但参数不同的方法
2.5 Stream流 File文件 IO
Java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标。
2.5.1读取控制台输入
可以使用System.in
包装在一个BufferedReader
对象中来创建一个字符流,绑定到控制台
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedReader
对象创建后,可以使用Read()
方法从控制台读取到一个字符,或者使用readLine()
方法读取一个字符串
2.5.2读写文件
输入流和输出流的类层次图
FileInputStream
该流用于从文件读取数据,有多种构造方法用来创建对象
// 可以使用字符串类型的文件名来创建一个输入流对象来读取文件
InputStream f = new FileInputStream("C:/java/hello");
FileOutputStream
该类用来创建一个文件并向文件中写数据。
如果该流在打开文件进行输出前,目标文件不存在,那么该流会创建该文件。
OutputStream f = new FileOutputStream("C:/java/hello")
2.5.3文件和I/O
需要扩展了解
File
类
FileReader
类
FileWriter
类
第三章
3.1类
- 如果一个类定义在某个包中,那么 package 语句应该在源文件的首行
- 如果源文件包含 import 语句,那么应该放在 package 语句和类定义之间。如果没有 package 语句,那么 import 语句应该在源文件中最前面
- import 语句和 package 语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明
public class Test{
private String name;
public Test(){ }
public Test(String name){
this.name = name;
}
public void setname(String name){
this.name = name;
}
public String getname(){
return this.name;
}
}
其他的基本没有什么了
3.2继承
继承的格式
class zi extends fu{
}
继承的特性
- 子类拥有父类非 private 的属性、方法。
- 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法。
- Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
- 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
继承关键字
- extends:类的继承(单一继承,只能继承一个父类)
- implements:接口的继承(可以继承多个接口)
- super :过super关键字来实现对父类成员的访问,用来引用当前对象的父类
- this:向自己的引用
- final:把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写:
3.3 方法的重写与重载
3.3.1重写
子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。
3.3.2方法的重写规则
- 参数列表与被重写方法的参数列表必须完全相同。
- 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类
- 访问权限不能比父类中被重写的方法的访问权限更低
- 父类的成员方法只能被它的子类重写
- 声明为 final 的方法不能被重写
- 声明为 static 的方法不能被重写,但是能够被再次声明
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法
- 构造方法不能被重写
3.3.3重载
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
3.3.4重载规则
- 被重载的方法必须改变参数列表(参数个数或类型不一样);
- 被重载的方法可以改变返回类型;
- 被重载的方法可以改变访问修饰符;
- 被重载的方法可以声明新的或更广的检查异常;
- 方法能够在同一个类中或者在一个子类中被重载。
- 无法以返回值类型作为重载函数的区分标准。
3.3.5重写与重载区别
3.4多态
多态就是同一个接口,使用不同的实例而执行不同操作
3.4.1虚函数
Java 中其实没有虚函数的概念,它的普通函数就相当于 C++ 的虚函数,动态绑定是Java的默认行为。
3.4.2实现方式
重写
接口
抽象类和抽象方法
3.5抽象类
3.5.1抽象类
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。
抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口
abstract class来定义抽象类。
public abstract class test{
}
3.5.2抽象方法
abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。
public abstract class test
{
private String name;
private String address;
private int number;
// 抽象方法
public abstract double method();
}
- 如果一个类包含抽象方法,那么该类必须是抽象类。
- 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。
3.5.3 总结
- 抽象类不能被实例化
- 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
- 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能
- 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法
- 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
3.6 接口
接口(英文:Interface),在JAVA中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
3.6.1声明
public interface name [extends 其他接口名] {
public void method1();
public void method2();
}
3.6.2调用接口
public class test1 implements name1, name2{
}
3.6.3注意
- 当类实现接口的时候,类要实现接口中所有的方法
- 类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面
- 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型
- 如果实现接口的类是抽象类,那么就没必要实现该接口的方法
- 一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法
第四章
4.1 泛型
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
泛型的定义格式
- <类型>: 指定一种类型的格式。这里的类型可以看成时形参
- <类型1,类型2,……>:指定多种类型的格式,多种类型使用逗号隔开
4.1.1泛型方法
利用泛型我们可以写一个泛型的方法,在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型编译器适当处理每一个方法的调用。
泛型方法的规则
- 所有泛型方法的声明都有一个类型参数声明部分,使用<>分隔,该类型参数声明部分在方法返回类型之前
- 每一个类型参数声明部分包含一个或多个类型参数,参数间使用逗号隔开。一个类型参数也被称为一个类型变量,是用于指定泛型类型名称的标识符
- 类型参数能被用来声明返回值的类型,并且能作为泛型方法得到实际的参数类型的占位符
- 泛型方法体的声明和其他方法一样。类型参数只能代表引用型类型(引用类型常见的有:
String
StringBuffer
ArrayList
HashSet
HashMap
等。),不能是原始类型(int
double
char
等)
定义格式
修饰符 <类型> 返回值类型 方法名(类型 变量名){}
public <T> void display(T t){}
4.1.2泛型类
定义格式:
修饰符 class 类名<类型> {}
public class Person<T>{}
T 是可以随便写的任意标识符,常见的如 T E K V 等形式
4.1.3泛型接口
定义格式
public interface test1<T>{
void show(T t);
}
public class test2<T> implements test1<T>{
@Override
public void show(T t){
System.out.println(t);
}
}
4.1.4类型通配符
类型通配符: <?>
List<?> : 表示元素类型未知的List,它的元素可以匹配任何的类型
这种带类型的通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中
List<? extends Number>(类型通配符上限): 它表示的类型是Number或者其子类
List<? super Number>(类型通配符下限): 它表示的类型是Number或者其父类型
4.1.5可变参数
使用可变参数可以定义一个方法接收不同数目的参数
public static int sum(int... a){
//方法体
}
// 传入的数据是以数组的形式存储在a中
4.2 Map
创建Map对象
- 多态方式
- 具体的实现类
HashMap
Map<String, String> map = new HAshMap<Strign, String>();
// 使用put方法添加元素
map.put("0000","test1");
map.put("0001","test2");
map.put("0002","test2");
// 如果键重复,之前的值会被覆盖
// 使用 remove(Object key) 删除键值对的元素
// 使用clear() 清除元素
// containsKey(Object key) 判断是否包含指定键
// containsValue(Object value)判断是否包含指定值
// isEmpty() 判断集合是否为空
// size() 返回键值对个数
// get(Object key) 获取值
// KeySet() 获取所有键的集合
// values() 获取所有值的集合
// entrySet() 获取所有键值对对象的集合
Set<Map.Entry<String, String>> entrySet = map.entrySet();
for(Map.Entry<String, String a : entrySet){
String key = a.getKey();
String value = a.getValue();
}
反射
概念:将类的各个组成部分封装为其他对象。
- 可以在程序运行中获取和操作对象
- 可以解耦,提高程序可扩展性
获取Class对象的方法
Class.forName("包.类名")
: 将字节码文件加载进内存返回Class对象多用于配置文件,将类名定义在配置文件中。读取文件,加载类
类名.class
: 通过类名的属性class获取多用于参数的传递
对象.getClass()
: Object方法中定义的多用与对象的获取字节码的方式
同一个字节码文件(*.class)在一次程序运行过程中,自会被加载一次,不论通过哪一种方法获取的Class对象都是同一个
Class对象功能
获取功能
- 获取所有成员变量
- 获取所有构造方法
- 获取所有成员方法
- 获取类名
具体可以直接查看java手册
注解
Java注解又称为Java标注,类、方法、变量、参数和包等都可以被标注。java标注可以通过反射获取标注的内容。