1、数组创建以及初始化
针对一维数组:
数据类型 数组名[] = new 数据类型[个数]
如 int a[] = new int[5];
针对多维数组:
数据类型 数组名[][] = new 数据类型[个数][]
注意:这里后面的列数可以不用指定大小,因为每一行的列数可以不一样
如 int a[][] = new int[3][];
a[0] = new int[2];
a[1] = new int[12];
在初始化时候,可以直接
int a[][] = {{1,2,3},
{11,22,333,444,555}};
2类
定义:
class 类名 extends 基类 implement 接口{
成员变量;
//访问权限:private,public,protected,以及友好变量(默认的,即在同一个包中可以访问)
//在这里变量可以初始化; int number = 10;
//注意成员变量中 类变量是加了static 通过类名来访问
成员函数
}
创建对象:
类名 变量 = new 类名(...);
注意:
(1) 基类 = 派生类;
3包package
在Java代码前加上package 以及路径名,比如package Base.Skill;此时这个文件存放在以当前项目路径为基准
\src\Base\Skill\Array.java 这样我们就可以找到这个Java文件
如果我们想引入这个Java文件,我们可以通过
import 包;
来实现比如import java.applet.*;
4抽象类及抽象方法
abstract class 抽象类名{
//用abstract修饰的方法,并且没有实体的函数
抽象方法;
普通成员函数{
}
}
抽象类不能用new来创建对象,只能通过子类来实现,一般用于设计某个类具有哪些功能,不关心具体怎么实现
具体怎么实现交给子类来完成
5接口interface
interface 接口名{
//final int MAX = 100;
常量定义;
//void fun();
方法申明
}
接口的出现是为了解决类不能实现继承多个类,但可以实现多个接口
使用:
class 类名 implements 接口名1,接口名2.。。{
//其中要在里面实现这个接口里面的申明的方法
}
在这里我们可以将实现这个接口的 类名 其实就当做是 由这个接口派生出来的类,这个
接口就是这个类的基类
接口名1 = 类名;
interface 接口名{
//常量定义;
final int MAX = 100;
//方法申明
void fun();
}
class A implements 接口名{
public void fun(){
System.out.println("aaaaaaaaaaaaaaaaaaaaaaa");
}
}
class 接口作为参数的类 {
public static void haha(接口名 b){
b.fun();
}
}
public class Interface {
public static void test() {
A a = new A();
System.out.println("实现接口的类执行的:");
a.fun();
接口名 b;
b = a;
System.out.println("接口的类执行的:");
b.fun();
System.out.println(b.MAX);
System.out.println("接口作为参数的执行的:");
接口作为参数的类.haha(a);
}
}
6匿名类及内部类
http://liusongjiang2003.blog.163.com/blog/static/138198822007329958185/
匿名类必须是某个类的子类或者是某个接口
abstract class 匿名类{
void printName(){
}
}
interface 匿名类接口{
void fun();
}
public class 匿名类测试 {
public static 匿名类 get匿名类(){
//返回一个匿名类
return new 匿名类(){
String name = "liu";
void printName(){
System.out.println(this.name);
}
};
}
public static 匿名类接口 get匿名类接口(){
//返回一个匿名类接口
return new 匿名类接口(){
String name = "liu";
public void fun(){
System.out.println(this.name);
}
};
}
public static void test(){
匿名类测试.get匿名类().printName();
匿名类测试.get匿名类接口().fun();
}
}
7Class类(主要是用在反射机制中获得对象各种描述)
java.lang.Class是一个比较特殊的类,它用于封装被装入到JVM中的类(包括类和接口)的信息
getClass方法
返回与调用该方法对象所属类关联的Class方面的信息,
如Date date1 = new Date();
Class c1 = date1.getClass();
注意c1和date2.getClass()是相同的,都是获得Date类方面的信息,不会获得对象的信息
getName()
返回所封装的类的名称
.class
返回与该类对应的Class对象。
Class clazz = String.class;
System.out.println(clazz.getName()); // java.lang.String
这个方法可以直接获得与指定类关联的Class对象,而并不需要有该类的对象存在
Class.forName(String className)
可以根据字符串参数所指定的类名获取与该类关联的Class对象
package org.whatisjava.reflect;
public class Foo {
public Foo() {
System.out.println("Foo()");
}
static {
System.out.println("Foo is initialized");
}
}
运行下面的代码:
Class clazz = Class.forName("org.whatisjava.reflect.Foo");
控制台会有如下输出:
Foo is initialized
newInstance()
Class还有一个有用的方法可以为类创建一个实例,这个方法叫做newInstance()。例如:
x.getClass.newInstance(),创建了一个同x一样类型的新实例。newInstance()方法调用默认构造器(无参数构造器)初始化新建对象。
forName和newInstance结合起来使用,可以根据存储在字符串中的类名创建对象。例如
Object obj = Class.forName(s).newInstance()
8复用类
重新使用类,其实复用就是“利用现成的东西”的意思,其实实现的两种方法就是java中经常听到的——组合和继承
其中主要涉及到代理模式
代理模式是对象的结构模式。代理模式给某一个对象提供给一个代理对象,并由代理对象去控制对原对象的引用及操作
主要是用到组合来实现这个功能
class 代理对象{
真正实际操作对象;
void operation(){
......
真正实际操作对象.operation();
.....
}
}
其中真正实际操作对象
class 真正实际操作对象{
void operation(){
......
}
}
package 代理模式;
abstract class 抽象操作对象 {
//操作
public abstract void operation();
}
class 真正实际操作对象 extends 抽象操作对象{
public void operation(){
System.out.println("真正实际操作对象做的");
}
}
class 代理对象 extends 抽象操作对象{
真正实际操作对象 p = new 真正实际操作对象();
public void operation(){
//.....
p.operation();
//.....
}
}
public class 代理 {
public static void main(String[] args) {
代理对象 m = new 代理对象();
m.operation();
}
}
9)线程
(1)线程的创建
创建线程的两种方式:
第一种创建线程的方式:实现Runnable接口的多线程
//先创建一个实现了Runnable 的类,在用这个Runnable 类来对线程初始化
class 实现Runnable接口的线程 implements Runnable {
String name;
public 实现Runnable接口的线程(String name){
this.name = name;
}
public void run() {
for(int i = 0;i < 10;i++)
System.out.println(this.name + " :" + i);
}
}
class 实现Runnable接口的多线程测试 {
public static void test(){
//这种方式创建线程,先创建一个实现了Runnable 的类,在用这个Runnable 类来对线程初始化
实现Runnable接口的线程 r1 = new 实现Runnable接口的线程("liu");
实现Runnable接口的线程 r2 = new 实现Runnable接口的线程("Hai");
//Thread(Runnable对象,"线程名字")或者是Thread(Runnable对象)
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
System.out.println(t1.getName() + " " + t2.getName());
}
}
第二种创建线程:扩展Thread类实现的多线程
//这种只要继承Thread,并实现里面的run方法即可
class MyThread extends Thread{
public MyThread(String name) {
super(name);
}
public void run() {
for(int i = 0;i<5;i++){
for(long k= 0; k <100000000;k++);
System.out.println(this.getName()+" :"+i);
}
}
}
public class 线程 {
public static void test(){
实现Runnable接口的多线程测试.test();
Thread t1 = new MyThread("阿三");
Thread t2 = new MyThread("李四");
t1.start();
t2.start();
}
}
(2)线程的状态
线程的五种状态:新状态、可运行状态、运行状态、等待/阻塞/睡眠状态、死亡态
让线程睡眠
public void run() {
for(int i = 0;i < 10;i++){
System.out.println(this.name + " :" + i);
//让线程睡眠
try {
Thread.sleep(3);
System.out.println( "线程睡眠");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
注意:
a、线程睡眠是帮助所有线程获得运行机会的最好方法。
b、线程睡眠到期自动苏醒,并返回到可运行状态,不是运行状态。sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行。
c、sleep()是静态方法,只能控制当前正在运行的线程。
(3)线程的优先级和线程让步yield()
//设置优先级
//优先级数字越高,优先级越大,线程默认优先级是5,Thread类中有三个常量
t1.setPriority(7);
t2.setPriority(8);
System.out.println("线程可以具有的最高优先级: " + Thread.MAX_PRIORITY);
System.out.println("线程可以具有的最低优先级: " + Thread.MIN_PRIORITY);
System.out.println("分配给线程的默认优先级: " + Thread.NORM_PRIORITY);
调用Thread.sleep():使当前线程睡眠至少多少毫秒(尽管它可能在指定的时间之前被中断)。
调用Thread.yield():不能保障太多事情,尽管通常它会让当前运行线程回到可运行性状态,使得有相同优先级的线程有机会执行。
调用join()方法:保证当前线程停止执行,直到该线程所加入的线程完成为止。然而,如果它加入的线程没有存活,则当前线程不需要停止。
(4) 线程的同步与锁
线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏。
a、同步
class Foo {
private int x = 100;
public int getX() {
return x;
}
public int fix(int y) {
x = x - y;
return x;
}
}
class MyRunnable implements Runnable {
private Foo foo =new Foo();
public static void test() {
MyRunnable r = new MyRunnable();
Thread ta = new Thread(r,"Thread-A");
Thread tb = new Thread(r,"Thread-B");
ta.start();
tb.start();
}
public void run() {
for (int i = 0; i < 3; i++) {
this.fix(30);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " :当前foo对象的x值= " + foo.getX());
}
}
public int fix(int y) {
return foo.fix(y);
}
}
Thread-A :当前foo对象的x值= 40
Thread-B :当前foo对象的x值= 40
Thread-B :当前foo对象的x值= -20
Thread-A :当前foo对象的x值= -20
Thread-B :当前foo对象的x值= -80
Thread-A :当前foo对象的x值= -80
从结果发现,这样的输出值明显是不合理的。原因是两个线程不加控制的访问Foo对象并修改其数据所致。
如果要保持结果的合理性,只需要达到一个目的,就是将对Foo的访问加以限制,每次只能有一个线程在访问。
这样就能保证Foo对象中数据的合理性了。
解决办法:
把竞争访问的资源类Foo变量x标识为private;
同步哪些修改变量的代码,使用synchronized关键字同步方法或代码如: public synchronized void run()
关于锁和同步,有一下几个要点:
1)、只能同步方法,而不能同步变量和类;
2)、每个对象只有一个锁;当提到同步时,应该清楚在什么上同步?也就是说,在哪个对象上同步?
3)、线程可以获得多个锁。比如,在一个对象的同步方法里面调用另外一个对象的同步方法,则获取了两个对象的同步锁。
4)、同步损害并发性,应该尽可能缩小同步范围。同步不但可以同步整个方法,还可以同步方法中一部分代码块。
5)、在使用同步代码块时候,应该指定在哪个对象上同步,也就是说要获取哪个对象的锁。例如:
public int fix(int y) {
synchronized (this) {
x = x - y;
}
return x;
}
当然,同步方法也可以改写为非同步方法,但功能完全一样的,例如:
public synchronized int getX() {
return x++;
}
与
public int getX() {
synchronized (this) {
return x;
}
}
效果是完全一样的。
6)要同步静态方法,需要一个用于整个类对象的锁,这个对象是就是这个类(XXX.class)。
例如:
public static synchronized int setName(String name){
Xxx.name = name;
}
等价于
public static int setName(String name){
synchronized(Xxx.class){
Xxx.name = name;
}
}
针对一维数组:
数据类型 数组名[] = new 数据类型[个数]
如 int a[] = new int[5];
针对多维数组:
数据类型 数组名[][] = new 数据类型[个数][]
注意:这里后面的列数可以不用指定大小,因为每一行的列数可以不一样
如 int a[][] = new int[3][];
a[0] = new int[2];
a[1] = new int[12];
在初始化时候,可以直接
int a[][] = {{1,2,3},
{11,22,333,444,555}};
2类
定义:
class 类名 extends 基类 implement 接口{
成员变量;
//访问权限:private,public,protected,以及友好变量(默认的,即在同一个包中可以访问)
//在这里变量可以初始化; int number = 10;
//注意成员变量中 类变量是加了static 通过类名来访问
成员函数
}
创建对象:
类名 变量 = new 类名(...);
注意:
(1) 基类 = 派生类;
3包package
在Java代码前加上package 以及路径名,比如package Base.Skill;此时这个文件存放在以当前项目路径为基准
\src\Base\Skill\Array.java 这样我们就可以找到这个Java文件
如果我们想引入这个Java文件,我们可以通过
import 包;
来实现比如import java.applet.*;
4抽象类及抽象方法
abstract class 抽象类名{
//用abstract修饰的方法,并且没有实体的函数
抽象方法;
普通成员函数{
}
}
抽象类不能用new来创建对象,只能通过子类来实现,一般用于设计某个类具有哪些功能,不关心具体怎么实现
具体怎么实现交给子类来完成
5接口interface
interface 接口名{
//final int MAX = 100;
常量定义;
//void fun();
方法申明
}
接口的出现是为了解决类不能实现继承多个类,但可以实现多个接口
使用:
class 类名 implements 接口名1,接口名2.。。{
//其中要在里面实现这个接口里面的申明的方法
}
在这里我们可以将实现这个接口的 类名 其实就当做是 由这个接口派生出来的类,这个
接口就是这个类的基类
接口名1 = 类名;
interface 接口名{
//常量定义;
final int MAX = 100;
//方法申明
void fun();
}
class A implements 接口名{
public void fun(){
System.out.println("aaaaaaaaaaaaaaaaaaaaaaa");
}
}
class 接口作为参数的类 {
public static void haha(接口名 b){
b.fun();
}
}
public class Interface {
public static void test() {
A a = new A();
System.out.println("实现接口的类执行的:");
a.fun();
接口名 b;
b = a;
System.out.println("接口的类执行的:");
b.fun();
System.out.println(b.MAX);
System.out.println("接口作为参数的执行的:");
接口作为参数的类.haha(a);
}
}
6匿名类及内部类
http://liusongjiang2003.blog.163.com/blog/static/138198822007329958185/
匿名类必须是某个类的子类或者是某个接口
abstract class 匿名类{
void printName(){
}
}
interface 匿名类接口{
void fun();
}
public class 匿名类测试 {
public static 匿名类 get匿名类(){
//返回一个匿名类
return new 匿名类(){
String name = "liu";
void printName(){
System.out.println(this.name);
}
};
}
public static 匿名类接口 get匿名类接口(){
//返回一个匿名类接口
return new 匿名类接口(){
String name = "liu";
public void fun(){
System.out.println(this.name);
}
};
}
public static void test(){
匿名类测试.get匿名类().printName();
匿名类测试.get匿名类接口().fun();
}
}
7Class类(主要是用在反射机制中获得对象各种描述)
java.lang.Class是一个比较特殊的类,它用于封装被装入到JVM中的类(包括类和接口)的信息
getClass方法
返回与调用该方法对象所属类关联的Class方面的信息,
如Date date1 = new Date();
Class c1 = date1.getClass();
注意c1和date2.getClass()是相同的,都是获得Date类方面的信息,不会获得对象的信息
getName()
返回所封装的类的名称
.class
返回与该类对应的Class对象。
Class clazz = String.class;
System.out.println(clazz.getName()); // java.lang.String
这个方法可以直接获得与指定类关联的Class对象,而并不需要有该类的对象存在
Class.forName(String className)
可以根据字符串参数所指定的类名获取与该类关联的Class对象
package org.whatisjava.reflect;
public class Foo {
public Foo() {
System.out.println("Foo()");
}
static {
System.out.println("Foo is initialized");
}
}
运行下面的代码:
Class clazz = Class.forName("org.whatisjava.reflect.Foo");
控制台会有如下输出:
Foo is initialized
newInstance()
Class还有一个有用的方法可以为类创建一个实例,这个方法叫做newInstance()。例如:
x.getClass.newInstance(),创建了一个同x一样类型的新实例。newInstance()方法调用默认构造器(无参数构造器)初始化新建对象。
forName和newInstance结合起来使用,可以根据存储在字符串中的类名创建对象。例如
Object obj = Class.forName(s).newInstance()
8复用类
重新使用类,其实复用就是“利用现成的东西”的意思,其实实现的两种方法就是java中经常听到的——组合和继承
其中主要涉及到代理模式
代理模式是对象的结构模式。代理模式给某一个对象提供给一个代理对象,并由代理对象去控制对原对象的引用及操作
主要是用到组合来实现这个功能
class 代理对象{
真正实际操作对象;
void operation(){
......
真正实际操作对象.operation();
.....
}
}
其中真正实际操作对象
class 真正实际操作对象{
void operation(){
......
}
}
package 代理模式;
abstract class 抽象操作对象 {
//操作
public abstract void operation();
}
class 真正实际操作对象 extends 抽象操作对象{
public void operation(){
System.out.println("真正实际操作对象做的");
}
}
class 代理对象 extends 抽象操作对象{
真正实际操作对象 p = new 真正实际操作对象();
public void operation(){
//.....
p.operation();
//.....
}
}
public class 代理 {
public static void main(String[] args) {
代理对象 m = new 代理对象();
m.operation();
}
}
9)线程
(1)线程的创建
创建线程的两种方式:
第一种创建线程的方式:实现Runnable接口的多线程
//先创建一个实现了Runnable 的类,在用这个Runnable 类来对线程初始化
class 实现Runnable接口的线程 implements Runnable {
String name;
public 实现Runnable接口的线程(String name){
this.name = name;
}
public void run() {
for(int i = 0;i < 10;i++)
System.out.println(this.name + " :" + i);
}
}
class 实现Runnable接口的多线程测试 {
public static void test(){
//这种方式创建线程,先创建一个实现了Runnable 的类,在用这个Runnable 类来对线程初始化
实现Runnable接口的线程 r1 = new 实现Runnable接口的线程("liu");
实现Runnable接口的线程 r2 = new 实现Runnable接口的线程("Hai");
//Thread(Runnable对象,"线程名字")或者是Thread(Runnable对象)
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
System.out.println(t1.getName() + " " + t2.getName());
}
}
第二种创建线程:扩展Thread类实现的多线程
//这种只要继承Thread,并实现里面的run方法即可
class MyThread extends Thread{
public MyThread(String name) {
super(name);
}
public void run() {
for(int i = 0;i<5;i++){
for(long k= 0; k <100000000;k++);
System.out.println(this.getName()+" :"+i);
}
}
}
public class 线程 {
public static void test(){
实现Runnable接口的多线程测试.test();
Thread t1 = new MyThread("阿三");
Thread t2 = new MyThread("李四");
t1.start();
t2.start();
}
}
(2)线程的状态
线程的五种状态:新状态、可运行状态、运行状态、等待/阻塞/睡眠状态、死亡态
让线程睡眠
public void run() {
for(int i = 0;i < 10;i++){
System.out.println(this.name + " :" + i);
//让线程睡眠
try {
Thread.sleep(3);
System.out.println( "线程睡眠");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
注意:
a、线程睡眠是帮助所有线程获得运行机会的最好方法。
b、线程睡眠到期自动苏醒,并返回到可运行状态,不是运行状态。sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行。
c、sleep()是静态方法,只能控制当前正在运行的线程。
(3)线程的优先级和线程让步yield()
//设置优先级
//优先级数字越高,优先级越大,线程默认优先级是5,Thread类中有三个常量
t1.setPriority(7);
t2.setPriority(8);
System.out.println("线程可以具有的最高优先级: " + Thread.MAX_PRIORITY);
System.out.println("线程可以具有的最低优先级: " + Thread.MIN_PRIORITY);
System.out.println("分配给线程的默认优先级: " + Thread.NORM_PRIORITY);
调用Thread.sleep():使当前线程睡眠至少多少毫秒(尽管它可能在指定的时间之前被中断)。
调用Thread.yield():不能保障太多事情,尽管通常它会让当前运行线程回到可运行性状态,使得有相同优先级的线程有机会执行。
调用join()方法:保证当前线程停止执行,直到该线程所加入的线程完成为止。然而,如果它加入的线程没有存活,则当前线程不需要停止。
(4) 线程的同步与锁
线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏。
a、同步
class Foo {
private int x = 100;
public int getX() {
return x;
}
public int fix(int y) {
x = x - y;
return x;
}
}
class MyRunnable implements Runnable {
private Foo foo =new Foo();
public static void test() {
MyRunnable r = new MyRunnable();
Thread ta = new Thread(r,"Thread-A");
Thread tb = new Thread(r,"Thread-B");
ta.start();
tb.start();
}
public void run() {
for (int i = 0; i < 3; i++) {
this.fix(30);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " :当前foo对象的x值= " + foo.getX());
}
}
public int fix(int y) {
return foo.fix(y);
}
}
Thread-A :当前foo对象的x值= 40
Thread-B :当前foo对象的x值= 40
Thread-B :当前foo对象的x值= -20
Thread-A :当前foo对象的x值= -20
Thread-B :当前foo对象的x值= -80
Thread-A :当前foo对象的x值= -80
从结果发现,这样的输出值明显是不合理的。原因是两个线程不加控制的访问Foo对象并修改其数据所致。
如果要保持结果的合理性,只需要达到一个目的,就是将对Foo的访问加以限制,每次只能有一个线程在访问。
这样就能保证Foo对象中数据的合理性了。
解决办法:
把竞争访问的资源类Foo变量x标识为private;
同步哪些修改变量的代码,使用synchronized关键字同步方法或代码如: public synchronized void run()
关于锁和同步,有一下几个要点:
1)、只能同步方法,而不能同步变量和类;
2)、每个对象只有一个锁;当提到同步时,应该清楚在什么上同步?也就是说,在哪个对象上同步?
3)、线程可以获得多个锁。比如,在一个对象的同步方法里面调用另外一个对象的同步方法,则获取了两个对象的同步锁。
4)、同步损害并发性,应该尽可能缩小同步范围。同步不但可以同步整个方法,还可以同步方法中一部分代码块。
5)、在使用同步代码块时候,应该指定在哪个对象上同步,也就是说要获取哪个对象的锁。例如:
public int fix(int y) {
synchronized (this) {
x = x - y;
}
return x;
}
当然,同步方法也可以改写为非同步方法,但功能完全一样的,例如:
public synchronized int getX() {
return x++;
}
与
public int getX() {
synchronized (this) {
return x;
}
}
效果是完全一样的。
6)要同步静态方法,需要一个用于整个类对象的锁,这个对象是就是这个类(XXX.class)。
例如:
public static synchronized int setName(String name){
Xxx.name = name;
}
等价于
public static int setName(String name){
synchronized(Xxx.class){
Xxx.name = name;
}
}