——年金波老师上课笔记
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 修饰的类,可以被其它包中的类访问
-
同一包中,不能访问其它类的private 属性和方法
-
同一包中,可以访问其它类的默认 属性和方法
-
同一包中,可以访问其它类的protected 属性和方法
-
同一包中,可以访问其它类的public 属性和方法
-
同一包中,不能访问父类的private 属性和方法
-
同一包中,可以访问父类的默认 属性和方法
-
同一包中,可以访问父类的protected 属性和方法
-
同一包中,可以访问父类的public 属性和方法
-
不同包中,无法访问不同包的其它类的private 属性和方法
-
不同包中,无法访问不同包的其它类的默认 属性和方法
-
不同包中,无法访问不同包的其它类的protected 属性和方法
-
不同包中,可以访问不同包的其它类的public 属性和方法
-
不同包中,无法访问父类的private 属性和方法
-
不同包中,无法访问父类的默认 属性和方法
-
不同包中,无法访问父类的protected 属性和方法
-
不同包中,可以访问父类的public 属性和方法
可以看到,类中的默认的属性和方法为protected修饰的
高级特性
static
1.修饰属性:所有的类的实习共享同一个属性
2.修饰方法:类名.方法名(调用方法)
3.{};用来初始化类的static属性
规则:
static修饰的方法不能访问非static变量(成员变量)
static修饰的方法不能访问非static方法(成员方法)
例:监控程序
监控程序:监控类实例的个数
ch06/InstanceCounter.java
package ch06;
public class InstanceCounter{
public static int count;
//初始化
static{
count=0;
}
{
count++;
}
public InstanceCounter(){
System.out.println("A new instance is created!");
}
public static void main(String args[]){
Object o1=new InstanceCounter();
Object o2=new InstanceCounter();
o1=null;o2=null;
System.gc();
System.out.println("Instance count:"+count);
}
//重写父类方法。范围不能变小. finalize 回收对象/实例占用的资源
public void finalize(){
count--;
System.out.println("Instance will be revoled by GC!");
}
}
Final修饰符
final:提高程序的健壮性
1.修饰类 该类不能被继承 (java.long.String 不能有子类)
2.修饰属性,改属性为常量 (程序运行期间值不能被改变的叫常量) 常量的赋值:在第一次被赋值之后,永远不能改变。常量的命名:全部大写 用下划线分隔 MAX_SIZE
3.修饰方法 该方法不能被重写
StringBuffer
StringBuffer 提高效率
缓存:提高效率
String : 做频繁的字符串连接操作,非常浪费系统空间
String str="abc";
str+="xyz";
str="abcxyz";
StringBuffer str=new StringBuffer("abc");
str.append("xyz");
str.toString()->StringBuffer->String;
StringBuilder与StringBuffer
StringBuilder和StringBuffer 使用方式完全相同
StringBuffer 线程安全
对象的比较
对象的比较:== 对于引用来说比较的地址值 。对于基本类型比较的数值
比较对象的内容:equals方法
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(obj=null)
return false;
if(this=obj)
return true;
if(this.getClass()!=obj.getClass())
return false;
Person p1=(Person)obj;
return this.getName().equals(p1)&&this.getAge()==p1.getAge();
}
代码覆盖率:测试用例是否可以覆盖(执行)所有代码
Java集合、反射、内部类、异常
集合(collection)
管理若干个对象
List:管理重复对象
1.Aarraylist:基于数组的实现
2.LinkedList:基于链表的实现
Set:管理不可重复的对象
1.HashSet:检索快
2.TreeSet:排序(自定义规则)
Map:做检索功能。键值对。key->value
例:HashMap:
ch06/ListTest.java
package ch06;
import java.util.*;
public class ListTest{
public static void main(String args[]){
//创建ArrayList
List aList=new ArrayList();
//add 添加
aList.add(new Integer(100));
aList.add(new Boolean(false));
aList.add(new Person("briup",false,1));
aList.add(new Person("briup-999",true,2));
out(aList);
outByIndex(aList);
}
/*
遍历list
*/
public static void out(List list){
Iterator it = list.iterator();
while(it.hasNext()){
Object obj=it.next();
System.out.println(obj);
}
}
public static void outByIndex(List list){
System.out.println("---------------------------------------");
int length=list.size();
for(int i=0;i<length;i++){
Object obj=list.get(i);
System.out.println(obj);
}
}
}
对集合进行遍历
迭代器:
java.util.Iterator{
boolean hasNext();//判断是否存在下一个元素
Object nest();//取下一个元素
}
fot(int i=0;i<3;i++){
it.next();
}
Object obj=it.next();
println(obj);
List:放置可重复的对象
Set :放置不可重复的对象 有对象的equals方法(返回true)和hashCode方法(返回的int值相等)决定。
HashSet:
TreeSet:
ch06/SetTest.java
package ch06;
import java.util.*;
public class SetTest{
public static void main(String args[]){
Set set=new HashSet();
Person p1=new Person("briup",false,1);
Person p2=new Person("briup--2",false,2);
Person p3=new Person("briup--3",false,3);
set.add(p1);
set.add(p2);
set.add(p3);
out(set);
}
public static void out(Set set){
Iterator it =set.iterator();
while(it.hasNext()){
Person p=(Person)it.next();
System.out.println(p);
}
}
}
hashCode来源于object对象
Object obj=new Object();
System.out.println(obj);
java.lang.Object@adfasdf123(由hashCode方法返回);
TreeSet:在向集合中添加元素的同时进行排序。对放入treeSet中的对象实现comparable接口并实现compareTo方法
Person 排序:
p1.compareTo(p2):p1>p2 return 1;p1=p2 return 0; p1<p2 return -1;
先排name :String类型按字母表的数序
如果相等
再按age
Map:->HashMap 键值对 key-》value
key value 可以是任何的object
一般情况下使用String作为key,value用Object
"briup-1" à new Person("briup-1",true,1);
ch06/MapTest.java
package ch06;
import java.util.*;
public class MapTest{
public static void main(String args[]){
Map map=new HashMap();
fill(map);//填充
out1(map);//遍历1
out2(map);//遍历2
}
public static void fill(Map map){
for(int i=0;i<1000;i++){
Person p = new Person("briup-"+i,true,1);
//第一个参数key值,第二个参数value值
map.put(p.getName(),p);//添加
}
}
public static void out1(Map map){
Set keySet=map.keySet();
Iterator it=keySet.iterator();
while(it.hasNext()){
String key=(String)it.next();
Person value=(Person)map.get(key);
System.out.println("key:"+key+"\t->"+"\tvalue:"+value);
}
}
public static void out2(Map map){
Set set=map.entrySet();
Iterator it=set.iterator();
while(it.hasNext()){
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);
}
}
}
存:put (key,value)
取:get(key)返回value
map遍历的两种方式:
1.获取map中所有的key值 :map.keySet();
2.Map.Entry封装了key 和value
反射:reflection
使用反射来处理class文件
java.lang.reflect.*;
Class{//描述一个类
Field//描述类中的属性
Method//描述类中的方法
Constructor//描述类的构造函数
}
反射的作用:
1、修改虚拟机中对象的属性(非常规)
可以直接修改private属性
person.setName();
2、条用对象的方法(非常规)
person.toString();
3、不通过new来创建类的对象的实例
new Person();
获取类的class实例:
1、Class clz=Class.forName("ch06.Person");//需要处理异常
2、类的引用.getClass();
Class clz=p1.getClass();
3、类名.class
Class clz=Person.class;
Class clazz=p1.getSuperclass();
5.primitive wraper classes的.TYPE语法
用于得到基本类类型:class clazz=Integer.TYPE;
ch06/ReflectTest.java
package ch06;
import java.lang.reflect.*;
public class ReflectTest{
public static void main(String args[]) throws Exception{
if(args.length!=1){
System.out.println("Please run the prog with class name");
System.exit(0);
}
Class clz=Class.forName(args[0]);
Method[] method=clz.getDeclaredMethods();
for(int i=0;i<method.length;i++){
System.out.println(method[i].getName());
}
}
}
ch06/ReflectAd.java//修改属性值
package ch06;
import java.lang.reflect.*;
public class ReflectAd{
public static void main(String args[]) throws Exception{
Person p1=new Person("briuo-999",true,10);
System.out.println("Before modify:"+p1);
Class clz=Person.class;
Field[] field =clz.getDeclaredFields();
for(int i=0;i<field.length;i++){
if(field[i].getName().equals("name")){
//调用setAccessible方法后可修改属性值
field[i].setAccessible(true);
//具体的修改方法:第一个参数说明要修改哪一个实例,第二个参数是修改后的值
field[i].set(p1,"briuo-888");
}
}
System.out.println("After modify:"+p1);
}
}
ch06///调用对象的方法//
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")){
method[i].invoke(p1,100);
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);
内部类
//解耦:数据跟程序解耦
//高内聚,低耦合
内部类:类里面的另外的类 。 共享外部类的资源;有效的避免命名冲突
成员内部类:
ch06.Outer_1.java
package ch06;
public class Outer_1{
public String str="abc";
public void show(){
System.out.println(str);
}
class Inner{
public String innerStr="ABC";
public void innerShow(){
System.out.println(innerStr);
System.out.println(str);
}
}
public static void main(String args[]){
Outer_1 outer=new Outer_1();
outer.show();
//实例化成员内部类
//创建成员内部类的实例必须依赖于外部类的实例
Outer_1.Inner inner=outer.new Inner();
inner.innerShow();
}
}
静态内部类:
不许要创建外部类的实例即可创建内部类实例。可以到达一定程度的封装
ch06/Outer_2.java
package ch06;
public class Outer_2{
public static String str="abc";
public static class Inner{
public String innerStr="xyz";
public void showPara(){
System.out.println(innerStr);
}
}
public static void main(String args[]){
//创建内部类的实例,不需要外围类的实例
Outer_2.Inner inner=new Outer_2.Inner();
inner.showPara();
//静态内部类只能访问外围类的静态属性和静态方法,因为静态内部类不持有外围类的实例
}
}
局部内部类:
类可以写在任意的地方
ch06/Outer_3.java
package ch06;
public class Outer_3{
public static void main(String args[]){
class Inner{
public String str="abc";
public void show(int number){
System.out.println(str);
System.out.println(number);
}
}
Inner inner =new Inner();
inner.show(100);
}
}
匿名内部类:
ch06.Outer_4.java
package ch06;
interface Test{
public void test(String message);
}
public class Outer_4{
public static void main(String args[]){
new Test(){
public void test(String message){
System.out.println(message);
}
}.test("briup");
//创建一个实现Test接口的匿名内部类。并同时调用test方法
}
}
异常(Exception)
1.异常
异常:程序无法正常运行 程序当中的错误
异常处理的机制:遇到异常代码,jvm寻找异常处理,如果找不到异常处理语句,则将该异常抛出至上层代码,如此反复,直至抛给虚拟机,终止程序运行
异常的分为两类:checked 异常(继承java.lang.Exception的异常(在代码中必须处理))。unchecked异常(java.lang.RuntimeException(不许要在程序编译的时候处理))
checked:编译期检查 如果源代码中没有进行处理,则无法通过编译
unchecked:运行期检查 编译的不会检查
Class.forName()->ClassNotFound
对于异常的处理:
1.try{//一般来说出来checked异常
//+可能有问题的代码
}catch(异常的类型1){
//+处理异常的代码
}catch(异常的类型1){
//+处理异常的代码
}finally{
//+必须执行的代码段 通常用来回收资源
}
2.throw 异常类型
ch07/ExceptionTest.java
return和finally(无论代码是否异常。都只返回finally的return)
ch07/ExceptionTest2.java
package ch07;
public class ExceptionTest2{
public static double divide(int a,int b){
/*if(b==0){
System.out.println("Can not / by zero");
return 0;
}*/
try{
return a/b;
}catch(ArithmeticException e){
System.out.println("Can not / by zero");
e.printStackTrace();
return 0;
}catch(Exception e1){
System.out.println("another Exception");
e1.printStackTrace();
return 0;
}finally{
return 100;
}
}
public static void main(String args[]){
System.out.println(divide(10,1));
System.out.println(divide(10,0));
System.out.println(divide(10,2));
}
}
3.自定义的异常:
一般都是unchecked;阐述系统中的业务逻辑错误
UersNotFoundException:找不到数据的用户
if(user==null)
throw new UserNotFoundException;
throw new NullPointerException;
实现:check异常
ch07/MyCheckedException.java
package ch07;
public class MyCheckedException extends Exception{
public MyCheckedException(){
super();
}
public MyCheckedException(String message){
super(message);
}
}
ch07/MyCheckedExceptionTest.java
package ch07;
public class MyCheckedExceptionTest {
public static void test(String para) {
if(para.equals("abc")){
throw new MyCheckedException("Parameter can not be abc");
}
System.out.println(para);
}
public static void main(String args[]){
try{
test("xyz");
test("abc");
test("string");
}catch(MyCheckedException e){
e.printStackTrace();
}
}
}
ch07/MyUnCheckedException.java
package ch07;
public class MyUncheckedException extends RuntimeException{
public MyUncheckedException(){
super();
}
public MyUncheckedException(String message){
super(message);
}
}
ch07/MyUncheckedExceptionTest.java
package ch07;
public class MyUncheckedExceptionTest {
public static void test(String para){
if(para.equals("abc")){
throw new MyUncheckedException("Wrong Parameter:");
}
}
public static void main(String args[]){
test("xyz");
test("abc");
test("string");
}
}
4.断言
偏向于测试
assert 布尔表达式(返回false的时候抛出AssertionError);
assert 布尔表达式:"断言信息";
开启断言:java-ea ch07/Test
当没开启断言的时候,对程序的效率没有任何影响
判断程序运行过程中变量的值是否符合预期
ch07/AssertTest.java
package ch07;
public class AssertTest{
public static void main(String args[]){
System.out.println("Before");
assert 1==1;
assert 1!=1:"wrong !!!";//类似于自定义异常的有参的函数构造
System.out.println("After");
}
}
判断程序运行的参数是否是"briup",如果不是则抛出异常
GUI 图形编程
容器:用来存放组件或者子容器
顶级容器:只能存放组件或者其它子容器(javax.swing.Jframe)
子容器:可以被其他容器所包含 也可以包含其他组件或者容器(javax.swing.JPanel)
组件:按钮。文本框。菜单 在javax.swing.*;包下
布局:用来表示组件或者容器的相对位置
1.FlowLayout 流式布局 组件顺序拜访
2.BorderLayout 边框布局 5个部分:south north west east center
3.GridLayout 表格布局 以行和列的形式将组件组织在一起
布局实例
ch08/FlowLayoutTest.java
package ch08;
import javax.swing.*;
import java.awt.*;
public class FlowLayoutTest{
private JFrame frame;
private Container contentPane;
private JButton btn_1,btn_2,btn_3,btn_4,btn_5;
public FlowLayoutTest(){
frame=new JFrame("Flow Layout Test");
frame.setSize(400,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initGUI();
}
public void initGUI(){
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");
contentPane.add(btn_1);
contentPane.add(btn_2);
contentPane.add(btn_3);
contentPane.add(btn_4);
contentPane.add(btn_5);
contentPane.add(s);
}
public void go(){
frame.setVisible(true);
}
public static void main(String args[]){
new FlowLayoutTest().go();
}
}
JMenultem 菜单项 "复制" "粘帖"
JMenu 菜单 "编辑" "查看"
JMenuBar 菜单条
m_1.add(new JSeparator()); //添加滚动条
菜单实例
ch07\MenuTest.java
package ch07;
import javax.swing.*;
import java.awt.*;
public class MenuTest
{
private JFrame frame;
private Container contentPane;
private JMenuItem m_item_1,m_item_2;
private JMenu m_1,m_2;
private JMenuBar mb;
public MenuTest()
{
frame=new JFrame("Menu Test");
frame.setBounds(200,200,400,200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane=frame.getContentPane();
initGUI();
}
public void initGUI()
{
contentPane.setLayout(new BorderLayout());
m_1=new JMenu("Edit");
m_2=new JMenu("About");
m_item_1=new JMenuItem("Ctrl c");
m_item_2=new JMenuItem("Ctrl v");
m_1.add(m_item_1);
m_1.add(new JSeparator());
m_1.add(new JMenuItem("test"));
m_2.add(m_item_2);
mb=new JMenuBar();
mb.add(m_1);
mb.add(m_2);
contentPane.add(mb,BorderLayout.NORTH);
}
public void go()
{
frame.setVisible(true);
}
public static void main(String[] args)
{
new MenuTest().go();
}
}
时间:EmotionEvent
事件源:Girl
事件处理范围:
interface EmotionListener{
happy(EmotionEvent e);
sad(EmotionEvent e);
}
观察者设计模式:
ch09/EmotionListener.java
ch09/EmotionEvent {
事件源 Object
时间模式 String
}
简易时钟
package ch07;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class ClockDemo implements ActionListener
{
private JFrame frame;
private JPanel clockPanel;
private Container contentPane;
public void actionPerformed(ActionEvent e)
{
}
public ClockDemo()
{
frame=new JFrame("ClockDemo");
contentPane=frame.getContentPane();
frame.setBounds(200,200,400,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initGUI();
}
public void initGUI()
{
contentPane.setLayout(new BorderLayout());
clockPanel=new ClockPanel();
contentPane.add(clockPanel);
}
public void go()
{
frame.setVisible(true);
}
public static void main(String []args)
{
new ClockDemo().go();
}
}
class ClockPanel extends JPanel implements ActionListener
{
private Timer timer;
//private java.util.Random rand;
private int i=-15,j=-15,k=-15;
public ClockPanel()
{
//rand=new java.util.Random();
timer=new Timer(20,this);
timer.start();
}
public void actionPerformed(ActionEvent e)
{
updateUI(); //4הJPanel
}
public void paint(Graphics g)
{
int cx=200,cy=200; //ԲЄλփ
//int x1=rand.nextInt(400);
//int y1=rand.nextInt(400);
//int x2=rand.nextInt(400);
//int y2=rand.nextInt(400);
i++;
if(0==(i+15)%60)
{
j++;
if(0==(j+15)%12)
{
k++;
}
}
double r1=150,r2=120,r3=100; //뾶
double alpha=Math.PI/30.0; //핫һΗ߶˹תŶȊ
g.clearRect(0,0,400,400);
//g.drawLine(x1,y1,x2,y2);
g.drawOval(50,50,300,300);
for(int n=0;n<60;n++)
{
double r0=r1-3.0;
if(0==n%5)
{
r0=r1-8.0;
}
g.drawLine((int)(cx+r0*Math.cos(n*alpha)),(int)(cy+r0*Math.sin(n*alpha)),(int)(cx+r1*Math.cos(n*alpha)),(int)(cy+r1*Math.sin(n*alpha)));
}
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)));
}
}
多线程
java优点:跨平台 多线程
进程:在os运行一个程序 用来完成一个独立完整的任务 至少要有一个线程(主线程)
线程:将一个完整的任务分解成若干的独立的小任务来完成 (本质)更多的抢占cpu的时间片,达到并怕执行的效果
计算机在同一时刻只能执行一条指令(单核)
线程由进程衍生出来。地址空间共享。data共享。code共享。是独立运行的分支(程序流)
java中如何实现线程:
1.继承Thread类
2.实现Runnable接口 解决单继承
都要实现run(),线程所要做的事情
public void run(){
}
如果run方法调用结束,线程结束
启动线程:线程的引用.start();
eclipse:
ch10/ThreadByExtends.java
ch10/ThreadByImplements.java
debug:断点debug 一步一步执行代码
普通线程和精灵Deamon线程
Thread.setDeamon(boolean);//设置普通线程为Deamon线程
Deamon线程:在后台运行的线程。对于Deamon线程始终依赖(生命周期)与另外一个线程
普通线程不存在依赖关系
setDeamon()必须在start();之前调用
线程的优先级:如果优先级不同,那么线程运行的先后顺序可以不一样(取决于操作系统的调度程序)
Thread.setPriority(0-10);
java.lang.Thread
Thread.sleep();让线程暂时停止运行某一特定的时间
Thread t=Thread.currentThread();获取当前运行的线程的实例(静态方法)
停止线程:不建议使用stop。可以设置标志位,通过对标志位的读取来终止线程的运行
boolean flag=true;
if(!flag)
return;
线程同步
1.为了保证多个线程操作同一个对象的完整性,可以对需要同步的方法使用synchronized修饰
2.使用synchronized修饰的方法,在调用的时候必须先获得该对象的锁(一个对象只有一把锁),只有获得了锁之后,同步方法才能被调用,调用之后锁被自动的释放
3.修饰代码块
synchronized(对象的引用){
需要同步的代码
}
传入的对象的引用被synchronized加锁。降低加锁的粒度。
ch10/SynchronizedTest.java
思索:deadlock 当两个对象相互持有对方所需要的锁的时候,并且都得不到释放,这时候产生死锁。。。。。。
ch10/DeadLockTest.java :锁得不到释放
wait():释放对象的锁 java.lang.Object
对象的引用.wait();释放引用锁指向的对象的锁,使当前程序停止运行,等待其他线程调用notify()进行通知后方可运行
sleep()不会释放对象的锁