Java SE 手册
JAVA的命名
小驼峰命名法,除第一个单词外,其他单词首字母大写;
大驼峰命名法,连第一个单词首字母也大写了,常用于类名,命名空间等
局部变量、实例变量、静态变量
静态变量前面加 static
关键字,而实例变量不加。程序运行时,实例变量
属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。
静态变量
不属于某个实例对象,而是属于类,也称为类变量,只要程序加载类类的 字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用类。
总之,实例变量必须创建对象后才能通过这个 对象来使用,而 静态变量则可以直接使用类名来引用。
public class ArrayTest01 {
int t; //实例变量,默认是0值
public static void main(String[] args){
int t = 1; //局部变量,在main方法内
System.out.println(t); //此时打印的是 局部变量t
ArrayTest01 aa = new ArrayTest01(); // 创建实例
System.out.println(aa.t); // 通过实例访问实例变量
}
}
#### 结果如下:
0
1
public class ArrayTest01 { // 创建类
//public ArrayTest01(){
// System.out.println("just test class object method");
//}
String aaa;
static int t; //实例变量,默认是0值
public static void test02(){ // 创建类方法,void 无返回值
System.out.println( t + "t" + 11); // 有int String 会转换成String
}
public static void test03(){
int j =0; // 注意,这里要写 int j 会报错,必须初始化j,即给它个初始值
for(int i=0;i<=10;i++){
j += i;
}
System.out.println(j);
}
public static void main(String[] args){
System.out.println(t); // 后面写(ArrayTest01.t)一样的;类的变量类的各种方法比如main 都可以引用
int t = 1; //局部变量,在main方法内
System.out.println(t); //此时打印的是 局部变量t
ArrayTest01 aa = new ArrayTest01(); // 创建实例
System.out.println(aa.t); // 通过实例访问实例变量
// System.out.println(aa.test02()); 这么写报错~!想想原因
aa.test02(); // 这里我想写个 x = aa.test02(); 就会报错
aa.test03(); // 因为在static 方法中引用任何实例变量都是非法的
ArrayTest01.test02();
}
}
### 结果:
0
1
0
0t11
55
0t11
abstract 修饰符
abstract 表示抽象的,是一个重要的修饰符,可以修饰类和方法。抽象类相当于一个类的半成品,需要子类继承并覆盖其中的抽象方法,这时子类才有创建实例的能力,如果子类没有实现父类的抽象方法,子类也要称为抽象类。说白类,抽象类就是类的规章准则。
有抽象方法的类一定是抽象类。反之,不然。
interface 接口
接口从本质上说就是一种特殊的抽象类。在接口中,所有的方法为公开、抽象方法:public abstract ;在接口中,所有的属性都是公开、静态的常量:public static final
public interface TestInterface { //我们先定义一个接口
final float PI = 3.14159f; //定义常量圆周率
float getArea(float r); //定义一个面积计算方法
float getCircumference(float r); //计算周长的方法
} // 接口中没有构造器也没有main方法
public class TestInterfaceCase implements TestInterface{
public float getArea(float r){
float area = PI*r*r; //计算圆的面积
return area; //返回圆的面积
}
public float getCircumference(float r){
float circumference = 2*PI*r; //计算圆周长
return circumference;
}
public static void main(String[] args){ // 继承接口的类必须要定义接口里面预留的所有方法,否则这个类还是抽象类,无法创建实例
TestInterfaceCase c = new TestInterfaceCase();
float f = c.getArea(2.0f);
System.out.println(Float.toString(f));
}
}
Java 包装类 以及 拆箱装箱
数据类型总共分为两大种:基本数据类型
、类类型
python ruby这种完全对象的语言,数字啥都都可以为对象。为了将数据类型作为对象来使用,Java提供了相对应的包装类。
int Ingteger; char Character; float Float; double Double;
byte Byte; short Short; long Long; boolean Boolean;
// 自动装箱
Integer i = 100; // 没有通过使用new来显示建立,Java自动完成
// 自动拆箱
int i =10;
Integer j = new Integer(i); // 手动装箱
int k = j.intValue(); // 手动拆箱操作
int i = 11;
Integer j = i; // 自动装箱
int k = j; //自动拆箱
⚠️Java为了提高效率,IntergerCache 类中有一个数组缓存了值从 -128 到 127的Integer对象。当我们调用 Integer.valueOf(int i)
的时候,如果i在-128 ~127 之间会直接从这个缓存中返回一个对象,否则就new一个Integer。
这里有个小难点,暂时不做深究
String StringBuffer StringBulder
- String:不可改变的Unicode字符序列
池化思想,把需要共享的数据放在池中,用一个存储区域来存放一些公共资源以减少存储空间的开销。
String s1 = "abc"; // 新创建,字符串常量池中没有该串,则会在池中创建一个串“abc”
String s2 = "abc"; // 串池中已经存在"abc",则s2会去指向"abc"而不会去创建一个新的
String s3 = new String("abc"); //直接去堆中开辟一个新空间,而不会去池中查找
- StringBuffer: 可改变的 Unicode 字符序列,允许并发操作,是线程安全的
String类在进行 字符串连接时会显得效率很低,就是因为它所产生的对象属性是不能够修改的,当连接字符串时也就只能新建对象。对于很多字符串连接,当使用StringBuffer类,使用这个类的对象来进行字符串连接不会产生多余的中间对象,从而优化效率。
String str = "a" + "b" + "c" //会产生"ab" "abc" 对象,占用空间,降低效率
// 解决方案:
String s = null;
StringBuffer sb = new StringBuffer("a");
sb.append("b");
sb.append("c");
s = sb.toString();
- StringBulder: 可改变的Unicode字符序列。操作同StringBuffer,只是不支持并发操作,非线程安全的。
内部类
内部类继承自 某个类或 实现某个接口,内部类的代码操作创建其的外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。
- 成员内部类:在外部类的内部直接定义一个类
public class TestOuter {
private static int i = 1;
private int j = 10;
private int k = 20;
public static void outer_f1(){
System.out.println("hi, it is outer_f1");
}
public static void outer_f2(){
System.out.println("hi, it is outer_f2");
}
//成员内部类中,不能定义静态成员;成员内部类中,可以访问外部类的所有成员;
class TestInner { //内部类
//static int inner_i = 100; //内部类中不允许定义静态变量
int j = 100; // 内部类和外部类的实例变量可以共存
int inner_i = 1;
void inner_f1(){
System.out.println(i); // 内部类可以访问内部类自己的变量,直接用变量名
System.out.println(j); //
System.out.println(this.j); // 与上面的效果一样
System.out.println(TestOuter.this.j); // 在内部类中访问外部类中与自己同名的实例变量用 `外部类名.this.变量名`
System.out.println(k);
outer_f1(); // 如果内部类中没有与外部类同名的变量,则可以直接用变量名访问外部类的变量
outer_f2();
}
}
// 外部类的非静态方法访问成员内部类
public void outer_f3(){
TestInner inner = new TestInner();
inner.inner_f1();
}
// 外部类的静态方法访问成员内部类,与在 外部类外部访问成员内部类一样
public static void outer_f4() {
TestOuter out01 = new TestOuter(); // 第一步建立外部类对象
TestInner inner = out01.new TestInner(); // 第二步根据外部类建立内部类的对象,这里的 out01 就是通过外部类引到内部类
inner.inner_f1(); // 第三步 访问内部类的方法
}
public static void main(String[] args){
outer_f4(); // 如果要直接创建内部类的对象,必须要创建一个外部类的对象来;你不能只用外部类就能创建出内部类对象出来
// 内部类的对象会悄悄的链接到创建它的外部类对象上。如果你是静态内部类(不允许有静态内部类变量),那就不需要对其外部类对象的引用
TestOuter out02 = new TestOuter();
TestOuter.TestInner out_in = out02.new TestInner();
out_in.inner_f1();
//out_in.inner_f2();
}
}
- 局部内部类:在外部类的方法中定义的内部类
与局部变量类似,局部内部类不能用public或private,它的作用域被限定在声明该类的方法块中。局部内部类的优势是 可以对外界完全隐藏起来,除了所在的方法外,对其他方法而言是不透明的。此外 与其他内部类比较,局部内部类不仅可以访问包含它的外部类成员,还可以访问局部变量,但这些局部变量必须被声明为final。
public class TestOuter02 { //局部内部类练习
private int s = 10;
private int k = 0;
public void funcl(){
final int s = 20;
final int j = 1;
class InnerClass{ //局部了内部类
int s = 30; //可以定义与外部类同名的变量
//static int m = 20; //不可以定义静态变量
void innerFunc(){ // 如果内部类没有外部类的 同名变量,在内部类中可以直接访问外部类的实例变量
System.out.println("外围类成员:"+k);
System.out.println("常量:"+s+"和"+j); // 可以访问外部类的局部变量(即方法内的变量),但变量必须是final的;如果变量同名,访问内部类的变量
System.out.println("常量"+ this.s); // 用this.变量名 访问的也是内部类变量
System.out.println("外部类成员变量:" + TestOuter02.this.s);
}
}
new InnerClass().innerFunc();
}
public static void main(String[] args){
//访问局部内部类必须先定义外部类对象
TestOuter02 out02 = new TestOuter02();
out02.funcl();
}
}
- 静态内部类:当内部类只是为了隐藏,不需要和外界发生联系时,可以将内部类声明为static
- 匿名内部类:就是没有名字的内部类
集合概述
所有抽象出来的数据结构和操作(算法)统称为 Java 集合框架(Java Collection Framework, JCF)...
Java的集合框架主要由一组用来操作对象的接口组成,不同接口描述一组不同的数据类型。核心接口主要有:Collection、List、Set、Map。
-
Collection 接口
Collection 接口是集合框架的基础,用于表示对象的集合。该接口中声明了所有集合都将拥有的核心方法,如添加、删除等,并提供了一组操作成批对象的方法等 -
List 接口
List 接口继承 Collection接口,元素允许重复,以元素添加的次序来放置元素,不会重新排列 -
Set 接口
Set 接口继承了 Collection 接口,Set中的对象元素不能重复,其添加后的不保证与添加的顺序一致 -
Map 接口
Map接口没有继承 Collection 接口。Map接口用于维护 键/值对(key/value)的集合,Map中的键key值不允许重复(Python和Ruby中的字典)
流和文件
- File类
java.io
包提供了一系列用于对 底层系统中文件进行处理。其中 File 类是最重要的一个类,该类可以获取文件信息,也可以对文件进行管理。
File(String pathname)// 构造方法,用于创建一个指定路径名的File对象
boolean canRead() // 判断文件或目录是否可读
boolean createNewFile() // 自动创建一个file对象指定文件名的空文件,只有在指定文件名不存在时才能创建成功
- 流
流(stream)源于 UNIX 中管道 pipe 的概率。JAVA中 流 代表程序中数据的流程,是以先进先出的方式发送信息的通道
JDBC 基础
JDBC(Java Database Connectivity)Java数据库连接是一种用于执行SQL语句的Java API。
暂略
Swing 图形界面
- 创建一个最基础的窗口界面
package cn.jk.cn.jk.codeTest;
import javax.swing.JFrame;
public class TestFrameDemo01 extends JFrame { // 继承自JFrame
public TestFrameDemo01(){
super("我的窗口"); //调用父类构造方法制定的窗口标题
this.setSize(300,200); //设定窗口大小
this.setLocation(100,100); //设定窗口左上角
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String args[]){
TestFrameDemo01 frame = new TestFrameDemo01();
frame.setVisible(true); // 使窗口可见
}
}
- 创建一个窗口,并自带2个按钮
package cn.jk.cn.jk.codeTest;
import javax.swing.*;
public class TestPanelDemo01 extends JFrame{
private JPanel jp; //声明面板对象
private JButton b1; // 声明按钮对象
private JButton b2;
public TestPanelDemo01(){
super("测试面板-x"); // 创建一个标题为 测试面板 的窗口
jp = new JPanel(); // 实例化面板对象
b1 = new JButton("x 1"); // 实例化一个按钮对象,该按钮上的文本为 "x 1"
b2 = new JButton("x 2");
// 将按钮添加到面板中
jp.add(b1);
jp.add(b2);
// 将面板添加到窗体框架中
this.add(jp);
this.setSize(300, 100);
this.setLocation(100,100);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args){
TestPanelDemo01 sp = new TestPanelDemo01();
sp.setVisible(true); // 若是false,只有窗口,里面按钮不显示
}
}
最终效果
- 按钮的窗口排布
import javax.swing.*;
import java.awt.GridLayout;
public class TestGridLayoutDemo01 extends JFrame {
private JPanel p;
private JButton b1,b2,b3,b4;
public TestGridLayoutDemo01(){
super("网格布局");
// 创建一个2行2列的网格布局管理器对象,并将该布局设置到面板中去
p = new JPanel(new GridLayout(2,2)); // 快捷写法
b1 = new JButton("Button 1");
b2 = new JButton("Button 2");
b3 = new JButton("Button 3");
b4 = new JButton("Button 4");
// 将按钮放置到面板中去
p.add(b1);
p.add(b2);
p.add(b4); // 特意掉个顺序测试一下
p.add(b3);
this.add(p);
this.setSize(300,200);
this.setLocation(100,100);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args){
TestGridLayoutDemo01 f = new TestGridLayoutDemo01();
f.setVisible(true);
}
}
- 创建监听类,实现单机按钮改变面板背景颜色的功能
package cn.jk.cn.jk.codeTest;
import javax.swing.*;
import java.awt.Color;
import java.awt.event.*;
public class TestColorChange01 extends JFrame {
JPanel p;
JButton btnRed, btnGreen, btnYellow;
public TestColorChange01(){
super("动作事件测试");
p = new JPanel();
btnRed = new JButton("面板会变红");
btnGreen = new JButton("面板会变绿");
btnYellow = new JButton("面板会变黄");
p.add(btnRed);
p.add(btnGreen);
p.add(btnYellow);
// 创建一个监听对象
ButtonListener b1 = new ButtonListener(); // ButtonListener是定义在ColorChange 类体内,是一个内部类。内部类可以直接访问外部类的其他成员,如 btnRed等
// 给按钮注册监听对象
btnRed.addActionListener(b1);
btnGreen.addActionListener(b1);
btnYellow.addActionListener(b1);
this.add(p);
this.setSize(300,200);
this.setLocation(100,100);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public class ButtonListener implements ActionListener{
// 重写 ActionLIstener 接口中的事件处理方法 actionPerformed()
public void actionPerformed(ActionEvent e){ // A
Object source = e.getSource(); // 获取事件源
// 判断事件源,进行相应的处理
if(source == btnRed){
// 设置面板的背景颜色是红色
p.setBackground(Color.red);
} else if(source == btnGreen){
// 设置面板的背景颜色是绿色
p.setBackground(Color.green);
} else{
// 设置面板的背景颜色是黄色
p.setBackground(Color.yellow);
}
}
}
public static void main(String[] args){
TestColorChange01 cf = new TestColorChange01();
cf.setVisible(true);
}
}
线程
线程 Thread 是程序中的执行路径,在 Java 虚拟机中由内核对象和 堆栈两部分组成,是操作系统或Java虚拟机的调度的运行单元。线程在多任务处理中有着举足轻重的作业。
线程(轻量级程序)类似一个程序,有开始、执行、结束,它是运行在程序内部的一个比进程还要小的单元。使用线程的主要应用在于可以在一个程序中同事运行多个任务。每个Java程序都至少有一个线程,即主线程。当一个Java程序启动时,JVM 会自动创建主线程,并在该线程中调用程序的main() 方法。
进程是一种“自包容”的运行程序,有自己的地址空间。比如打开电脑的 任务管理器,就可以显示当前所有的进程。
线程是进程内部单一的一个顺序控制流。基于进程的特点,允许计算机同时运行两个或更多的成怒。基于线程的多任务处理环境,线程是最小的处理单位。多线程程序在更低层次中引入多任务处理。