杰普Core Java课程笔记2
——年金波老师上课笔记
Java面向对象基础
面向对象的思想:
封装、继承、多态
1.封装:隐藏对象的属性和方法 private
2.继承:对象重用 减少代码冗余 extends
单继承 将父类的属性和方法 继承到子类中
3.多态:同一个类域(存在继承关系的类)的不同对象在调用相同方法的时候表现不同
封装:修饰符 public protected private 无 修饰属性和方法
public :其他类可以任意访问 自己类可以访问
protected:自己访问 子父类之间 相同包下
无:自己访问 相同的包下
class Person{
String name;
}
private 只有自己能访问
private Person(){
}
public static Person newone(){
return new Person();
}
Person p=Person.newone();
单例模式:在整个虚拟机中只有一个类的实例
专门处理日期
java.util.Date 濒临灭绝
java.util.Calendar 不能new
//指向系统当前时间
Calendar cal=Calendar.getInstance()
//获取年份
cal.get(Calendar.YEAR);
//获取月份
cal.get(Calendar.MONTH);
extends 后只能有一个父类:
this 表示当前类的实例
this.属性
this.方法(参数)
this();调用构造函数
this(参数):
方法的重载和重写
重载:在一个类内有多个相同(名字上)的方法
参数类型不同。参数个数不同。参数的顺序不同。
返回值:返回值是否相同对重载不构成影响
Person{
public void print(){}
public void print(String message){}
public void print(int level){}
}
构造函数也可以重载:
重写:发生在子类 。重新定义父类中的方法。
方法签名要跟父类相同
方法签名:返回值+方法名+方法参数(个数,顺序,类型 都相同)
super:访问父类中的属性和方法
super.父类属性
super.父类方法(参数)
super()//父类的构造器
super(参数)//调用父类的重载构造器
ch05/Father.java
package ch05;
public class Father{
protected String name;
protected int age;
public Father(){}
public Father(String name, int age){
this.name=name;
this.age=age;
}
public void print(){
System.out.println("Name :"+this.name +"\tAge :"+this.age);
}
}
ch05/Son.java
package ch05;
import java.u
public class Son extends Father{
public String[]hobby;
public Son(){}
public Son(String name, int age,String hobby []){
super(name,age);
//this.name=name;
//this.age=age;
this.hobby=hobby;
}
public void print(){
super.print();
System.out.println("Hobby:"+this.hobby);
}
public static void main(String args[]){
Son son=new Son("briup",1,new String []{"reading","gaming"});
son.print();
}
}
方法的参数传递
1.值传递:对于基本的参数类型 值拷贝(把外围的值拷贝到方法内供方法使用,对方法外的变量不构成影响)
mian(){
int a=10;
change(a);
System.out.println(a);
}
static void change(int a){
a=100;
System.out.println(a);
}
先打印出100
后打印出10
2.引用传递:地址值
Person p=new Person("test",18);
change(p);
System.out.println(p.getName());
}
static void change(Person p){
p.setName("briup")
System.out.println(p.getName());
}
都打印出briup
类的初始化:
静态初始化代码段: static {}
实例初始化代码段: {}
构造方法:
ch05/InitTest.java
package ch05;
public class InitTest{
static {
//在jvm装载类的时候调用,无论创建多少个对象,都只会被调用一个。通常用来初始化静态成员变量
System.out.println("Static block is invoked!");
}
{
//创建实例之前进行调用,先与构造器
System.out.println("Instance block is invoked!");
}
public InitTest(){
System.out.println("Constructor method is invoked!");
}
public static void main(String args[]){
new InitTest();
System.out.println("--------");
new InitTest();
}
}
接口:interface 来声明。只允许定义常量 (public static final String str="abc")和 空方法(抽象方法,没有实现)
public interface Test {
public void test(String test);
}
接口的作用:用来描述规范,被其他的接口或者类 实现或者继承
具体的类 实现(implements) 接口(一个或者多个,多个之间用","分割),必须实现接口内的所有方法
接口 继承(extends) 接口
接口不能被实例化。接口在一定程度上弥补类java的单继承
抽象类:如果一个类没有完全的实现接口中的所有的方法,必须把没有实现的方法声明为抽象方法。。(abstract)
如果一个类中有一个抽象方法,那么该类必须被声明为抽象类(public abstract class)
功能更普通类是一样,抽象类可以分担子类的一本分功能
方法 实例化 创建引用
实体类: 全部实现 可以 是
抽象类: 部分实现 不可以 是
接口: 全部不实现 不可以 是
Son son=new Son();
Father son=new Son();
Son s=(Son)son;如果没有就报错:ClassCastingException
因为 Son 继承 Father
Father -> Son
抽象类 -> 继承了抽象类的具体类
接口-> 实现接口的具体类
casting: 类型转换,引用或者类类型
向上转换:不需要显示的类型转换
向下转换:要显示的强制类型转换
上:father
下:son
ch05/log.java
ch05/Baselog.java
ch05/SystemLogImoI.java
ch05/FilelogImo.java
ch05/LogTest.java
员工管理:
对于员工:cr(retravel)ud
DML insert
DDL drop
存放员工的数据结构-》queue
EmppoyeeDate{ Employee [] emArray;
create();//增加员工
find(int id);
update 更新
delete
}
Java中类的属性和方法的访问控制
- 类没有protected和private修饰符
- 被public 修饰的类,可以被其它包中的类访问
- 没有被public 修饰的类,不能被其它包中的类访问
static修饰的方法不能访问非static变量(成员变量)
static修饰的方法不能访问非static方法(成员方法)
System.out.println("A new instance is created!");
public static void main(String args[]){
Object o1=new InstanceCounter();
Object o2=new InstanceCounter();
System.out.println("Instance count:"+count);
//重写父类方法。范围不能变小. finalize 回收对象/实例占用的资源
System.out.println("Instance will be revoled by GC!");
1.修饰类 该类不能被继承 (java.long.String 不能有子类)
2.修饰属性,改属性为常量 (程序运行期间值不能被改变的叫常量) 常量的赋值:在第一次被赋值之后,永远不能改变。常量的命名:全部大写 用下划线分隔 MAX_SIZE
StringBuffer str=new StringBuffer("abc");
str.toString()->StringBuffer->String;
StringBuilder和StringBuffer 使用方式完全相同
对象的比较:== 对于引用来说比较的地址值 。对于基本类型比较的数值
Person p1 = new Person("briup",13);
Person p2 = new Person("briup",13);
p1.equals(p2) -> true :内容相同 false ->内容不同
equals的来源:java.long.object ,默认实现相当与== , 重写该方法完成自定义的内容比较
public boolean equals(Object obj){
if(this.getClass()!=obj.getClass())
return this.getName().equals(p1)&&this.getAge()==p1.getAge();
public static void main(String args[]){
aList.add(new Boolean(false));
aList.add(new Person("briup",false,1));
aList.add(new Person("briup-999",true,2));
public static void out(List list){
Iterator it = list.iterator();
public static void outByIndex(List list){
System.out.println("---------------------------------------");
boolean hasNext();//判断是否存在下一个元素
Set :放置不可重复的对象 有对象的equals方法(返回true)和hashCode方法(返回的int值相等)决定。
public static void main(String args[]){
Person p1=new Person("briup",false,1);
Person p2=new Person("briup--2",false,2);
Person p3=new Person("briup--3",false,3);
public static void out(Set set){
java.lang.Object@adfasdf123(由hashCode方法返回);
TreeSet:在向集合中添加元素的同时进行排序。对放入treeSet中的对象实现comparable接口并实现compareTo方法
p1.compareTo(p2):p1>p2 return 1;p1=p2 return 0; p1<p2 return -1;
一般情况下使用String作为key,value用Object
"briup-1" à new Person("briup-1",true,1);
public static void main(String args[]){
public static void fill(Map map){
Person p = new Person("briup-"+i,true,1);
public static void out1(Map map){
Iterator it=keySet.iterator();
Person value=(Person)map.get(key);
System.out.println("key:"+key+"\t->"+"\tvalue:"+value);
public static void out2(Map map){
Map.Entry entry=(Map.Entry)it.next();
String key=(String)entry.getKey();
Person value=(Person)entry.getValue();
System.out.println("key:"+key+"\t->"+"\tvalue:"+value);
1.获取map中所有的key值 :map.keySet();
1、Class clz=Class.forName("ch06.Person");//需要处理异常
Class clazz=p1.getSuperclass();
5.primitive wraper classes的.TYPE语法
用于得到基本类类型:class clazz=Integer.TYPE;
public static void main(String args[]) throws Exception{
System.out.println("Please run the prog with class name");
Class clz=Class.forName(args[0]);
Method[] method=clz.getDeclaredMethods();
for(int i=0;i<method.length;i++){
System.out.println(method[i].getName());
public static void main(String args[]) throws Exception{
Person p1=new Person("briuo-999",true,10);
System.out.println("Before modify:"+p1);
Field[] field =clz.getDeclaredFields();
for(int i=0;i<field.length;i++){
if(field[i].getName().equals("name")){
//具体的修改方法:第一个参数说明要修改哪一个实例,第二个参数是修改后的值
System.out.println("After modify:"+p1);
Method [] method=clz.getDeclaredMethods();
for (int i=0;i<method.length;i++){
if(method[i].getName().equals("toString")){
String resule=(String)method[i].invoke(p1);
System.out.println("@@@@@@@@@@@@2result");
if(method[i].getName().equals("setAge")){
System.out.println("!!!!!"+p1);
不通过new来创建类的对象的实例:通过字符串形式命名,将类名迁移到配置文件中(通常是文本文件形式),根据横序的运行,动态的创建类得实例
Constructor constructor =clz.getConstructor(String.class, boolean.class, int.class);
Object obj=constructor.newInstance("briup-000",false,100);
System.out.println("Constructor a new instance without new :" +obj);
内部类:类里面的另外的类 。 共享外部类的资源;有效的避免命名冲突
public static void main(String args[]){
Outer_1.Inner inner=outer.new Inner();
不许要创建外部类的实例即可创建内部类实例。可以到达一定程度的封装
public static String str="abc";
public static void main(String args[]){
Outer_2.Inner inner=new Outer_2.Inner();
//静态内部类只能访问外围类的静态属性和静态方法,因为静态内部类不持有外围类的实例
public static void main(String args[]){
public void test(String message);
public static void main(String args[]){
public void test(String message){
//创建一个实现Test接口的匿名内部类。并同时调用test方法
异常处理的机制:遇到异常代码,jvm寻找异常处理,如果找不到异常处理语句,则将该异常抛出至上层代码,如此反复,直至抛给虚拟机,终止程序运行
checked:编译期检查 如果源代码中没有进行处理,则无法通过编译
Class.forName()->ClassNotFound
return和finally(无论代码是否异常。都只返回finally的return)
public static double divide(int a,int b){
System.out.println("Can not / by zero");
}catch(ArithmeticException e){
System.out.println("Can not / by zero");
System.out.println("another Exception");
public static void main(String args[]){
System.out.println(divide(10,1));
System.out.println(divide(10,0));
System.out.println(divide(10,2));
UersNotFoundException:找不到数据的用户
throw new UserNotFoundException;
throw new NullPointerException;
public class MyCheckedException extends Exception{
public MyCheckedException(String message){
ch07/MyCheckedExceptionTest.java
public class MyCheckedExceptionTest {
public static void test(String para) {
throw new MyCheckedException("Parameter can not be abc");
public static void main(String args[]){
ch07/MyUnCheckedException.java
public class MyUncheckedException extends RuntimeException{
public MyUncheckedException(){
public MyUncheckedException(String message){
ch07/MyUncheckedExceptionTest.java
public class MyUncheckedExceptionTest {
public static void test(String para){
throw new MyUncheckedException("Wrong Parameter:");
public static void main(String args[]){
assert 布尔表达式(返回false的时候抛出AssertionError);
public static void main(String args[]){
assert 1!=1:"wrong !!!";//类似于自定义异常的有参的函数构造
顶级容器:只能存放组件或者其它子容器(javax.swing.Jframe)
子容器:可以被其他容器所包含 也可以包含其他组件或者容器(javax.swing.JPanel)
组件:按钮。文本框。菜单 在javax.swing.*;包下
2.BorderLayout 边框布局 5个部分:south north west east center
3.GridLayout 表格布局 以行和列的形式将组件组织在一起
private Container contentPane;
private JButton btn_1,btn_2,btn_3,btn_4,btn_5;
frame=new JFrame("Flow Layout Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane=frame.getContentPane();
contentPane.setLayout(new FlowLayout());
btn_1=new JButton("fisrt btn");
btn_2=new JButton("second btn");
btn_3=new JButton("third btn");
btn_4=new JButton("fourth btn");
btn_5=new JButton("fifth btn");
public static void main(String args[]){
m_1.add(new JSeparator()); //添加滚动条
private Container contentPane;
private JMenuItem m_item_1,m_item_2;
frame=new JFrame("Menu Test");
frame.setBounds(200,200,400,200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane=frame.getContentPane();
contentPane.setLayout(new BorderLayout());
m_item_1=new JMenuItem("Ctrl c");
m_item_2=new JMenuItem("Ctrl v");
m_1.add(new JMenuItem("test"));
contentPane.add(mb,BorderLayout.NORTH);
public static void main(String[] args)
public class ClockDemo implements ActionListener
private Container contentPane;
public void actionPerformed(ActionEvent e)
frame=new JFrame("ClockDemo");
contentPane=frame.getContentPane();
frame.setBounds(200,200,400,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane.setLayout(new BorderLayout());
public static void main(String []args)
class ClockPanel extends JPanel implements ActionListener
//private java.util.Random rand;
private int i=-15,j=-15,k=-15;
//rand=new java.util.Random();
public void actionPerformed(ActionEvent e)
double r1=150,r2=120,r3=100; //뾶
double alpha=Math.PI/30.0; //핫һΗ߶˹תŶȊ
g.drawLine(cx,cy,(int)(cx+r1*Math.cos(i*alpha)),(int)(cy+r1*Math.sin(i*alpha)));
g.drawLine(cx,cy,(int)(cx+r2*Math.cos(j*alpha)),(int)(cy+r2*Math.sin(j*alpha)));
g.drawLine(cx,cy,(int)(cx+r3*Math.cos(k*alpha)),(int)(cy+r3*Math.sin(k*alpha)));
进程:在os运行一个程序 用来完成一个独立完整的任务 至少要有一个线程(主线程)
线程:将一个完整的任务分解成若干的独立的小任务来完成 (本质)更多的抢占cpu的时间片,达到并怕执行的效果
线程由进程衍生出来。地址空间共享。data共享。code共享。是独立运行的分支(程序流)
Thread.setDeamon(boolean);//设置普通线程为Deamon线程
Deamon线程:在后台运行的线程。对于Deamon线程始终依赖(生命周期)与另外一个线程
线程的优先级:如果优先级不同,那么线程运行的先后顺序可以不一样(取决于操作系统的调度程序)
Thread.sleep();让线程暂时停止运行某一特定的时间
Thread t=Thread.currentThread();获取当前运行的线程的实例(静态方法)
停止线程:不建议使用stop。可以设置标志位,通过对标志位的读取来终止线程的运行
1.为了保证多个线程操作同一个对象的完整性,可以对需要同步的方法使用synchronized修饰
2.使用synchronized修饰的方法,在调用的时候必须先获得该对象的锁(一个对象只有一把锁),只有获得了锁之后,同步方法才能被调用,调用之后锁被自动的释放
传入的对象的引用被synchronized加锁。降低加锁的粒度。
思索:deadlock 当两个对象相互持有对方所需要的锁的时候,并且都得不到释放,这时候产生死锁。。。。。。
ch10/DeadLockTest.java :锁得不到释放
wait():释放对象的锁 java.lang.Object
对象的引用.wait();释放引用锁指向的对象的锁,使当前程序停止运行,等待其他线程调用notify()进行通知后方可运行