1、Java快速入门

  

第一课 Java基础
1. ubuntu上环境搭建 (建议使用我们提供的VMWare映象文件)
如果要自己安装ubuntu, 请参考<韦东山Android系统视频使用手册.pdf>
ubuntu 12.04.5 这是一个长期支持的版本
硬盘空间至少预留80G
a. root分区 : 20G, 从其中划出6G用作swap
b. work分区 : 60G
c. 内存 : 4G

安装Java开发环境
sudo apt-get update
sudo apt-get install openjdk-7-jdk
sudo apt-get install openjdk-7-jre

2. 第1个JAVA程序 (和C对比)

编译的方法:javac Hello.java

运行的方法:java hello

3. JAVA数据类型
基本数据类型:boolean, byte, char(2字节), short, int, long, float, double
引用数据类型:数组、类对象、接口(引用数据类型指的是变量所指向的数据在堆中,比如:int p2[] = {1,2,4},数据1,2,4在堆中,p2在栈上,其值是堆的地址),引用和C语言中的指针比较类似

引用数据类型使用new来分配,不需要自己释放,把变量设为null即可

栈内存、堆内存
数据类型转换(自动转换(发生的前提是数据转换后不会丢失), 强制转换)

short s=1;s=s+1会出错,因为对于byte,short的运算,为了保证精度,会自动转换为int,其不能直接赋给short类型,改为s=(short)(s+1)

sourceinsight编写的文件是以ascii码编译的,java编译器是以UTF-8来解析字符的,所以如果文件中存在汉字,会存在无法解析的情况,所以需要使用UE把该文件转换成UTF-8格式

4. 语句:跟C完全一样

5. 方法(函数)

6. 方法重载、参数传递

重载指的是函数名相同,参数类型或者参数个数不同,返回值类型的不同不是重载

int p[] = new int[1];p[0]=123;fun2(p);这个时候p[0]的值会改变(public static void fun2(int[] p){p[0]=100})

第二课 面向对象程序设计
1. 类的引入
C语言是面向过程的
出一道题:写一个程序,输出张三、李四两个人的姓名

定义一个类(class  A),实例化这个变量(A a),a就是个对象

构造函数格式:public 类名称(类型 参数......)//其没有返回值,可以有多个构造方法

{

  语句;

}

static修饰的类方法属于类,通过“类名.方法”来调用

在类中通过一个大括号”{}”括起来的就是构造块,通过构造块扩起来的代码在任何构造函数被调用之前会被调用执行

大括号“{}”之前加上一个static修饰就是静态代码块,实例化第一个对象之前执行,并且只执行一次,在执行构造块和构造方法,再之后实例化都不会再次执行静态代码块。

类中的main函数通过static修饰是为了让虚拟机不用实例化对象就能执行main函数

2. 封装性

private修饰的变量和方法只能被类的内部方法所访问,不能被外部所访问

private本类可访问;default本包可访问;protected本包、其他包的之类可访问;public所有都可访问

3. 继承性

实例化子类对象时,先调用父类的构造方法,再调用子类的构造方法(如果子类构造函数中没有super等语句,在子类的构造函数中第一行默认会添加一句super();表示调用父类的默认无参构造函数);

如果父类有个构造方法是“类名(参数1)”,则在子类构造方法中第一句加上“super(参数1)”,在实例化一个对象时会先调用父类的构造方法“类名(参数1)”

final类不能有子类;final方法不能被覆写;final变量变成常量,不能被修改

继承的限制:1、父类的private修饰属性和方法不能被之类继承,对应私有属性,如果有公开的方法获得私有属性,子类可以调用该方法

      2、子类覆写的方法不能缩小权限,比如父类的public方法a,子类也只能覆写为public;

在class前加上abstract修饰的类是抽象类,其类内部除了有属性、普通方法外还有抽象方法()在方法的访问权限和返回值之间加上abstract修饰的方法),抽象方法仅需要声明,不需要实现;

抽象类不能实例化对象,子类必须覆写全部抽象方法;

接口:interface 接口名称{全局常量;抽象方法}

接口和抽象类相似,其模板作用,子类可以继承多个接口,子类必须覆写全部抽象方法

(子类只能extends继承一个父类)

class A extends D implements B,C{}//B和C是接口,D是普通类火灾抽象类

4. 多态性

Son son = new Son();Father f = son;//如果fun()在父类Father和子类Son中都定义,f.fun()只能调用被子类覆写的方法;而如果fun仅在son中定义,则不能调用f.fun(),不能调用只在子类中定义的方法;而如果fun仅在father中定义,则f.fun就是调用自己的fun函数(这就是向上转换,把子类的对象赋给父类)

Father f = new Son();Son son = (Son)f;//在进行对象的向下转换前,必须首先发生对象的向上转换(比如声明父类对象的时候使用new 子类)(向下转换,把父类的对象赋值给子类,需要强制转换)

向上转换使用场景:在main中定义了一个函数,函数的参数是父类,这时候在调用这个函数的时候可以传子类;

eg:public static void main(String args[]){   //Son和Daughter是Father的子类

  Father f = new Father();

  Son s = new Son();

  Daughter d = new Daughter();

  print(f);

  print(s);

  print(d);

}

  public static void print(Father f){

  f.printfInfo();

}

instanceof用来判断对象是不是某个类的实例 eg:if(f instanceof Father)

向下转换的使用场景:

eg:public static void main(String args[]){   //Son和Daughter是Father的子类

  Father f = new Father();

  Son s = new Son();

  Daughter d = new Daughter();

  printAction(f);

  printAction(s);

  printAction(d);

}

  public static void printAction(Father f){

  if(f instanceof Son){

    Son son = (Son)f;

    son.playGame();

  }

  else  if(f instanceof Daughter){

    Daughter d= (Daughter)f;

    d.dance();

  }

  else  if(f instanceof Father){  //父类的instanceof必须放在最后面,子类对象 instanceof Father的时候也是真的

    f.drink();

  }

}

5. 异常

自己处理:

try

{执行语句}

catch(异常)

捕获异常后执行的语句

finally{

不管有无异常都会执行的语句,finally可有可无

让别人处理:

1、在调用语句的函数“{”前面加上throws 异常,其表示扔给函数的调用者A处理;

2、把调用者A放到try语句块中,并加上catch来处理;

3、也可以在调用者A所属的函数出加上throws来上仍

4、对于有些异常需要自己处理一部分,也需要调用者处理一部分的情况时,这时候需要在自己处理的catch语句块中的最后一行加上throw 

  eg:catch (ArithmeticException e){

    System.out.println("div:"+e);

    throw e;

    }

通过catch (异常A){

}catch(异常B){

}catch (异常C){

}通过catch捕获多个异常时,子异常必须在前面,否则父异常会把所有异常捕获

如果try或catch块中有return或throw语句,会先执行finally块,在返回执行return或者throw语句,如果在fianlly中直接return返回了就不会在执行了,所有不要在finally中加return语句。

对于可查(代码不需要运行就知道运行到此处肯定会抛出异常)异常必须处理(自己处理或者抛出去)

对于不可查异常可以不处理,系统也会自动抛出去


参考文章:
深入理解java异常处理机制
http://blog.csdn.net/hguisu/article/details/6155636


6. 包和权限
javac A.java // 将在当前目录下生成A.class
能否把这些class文件存放于其他目录呢?

在A.class 中添加一句“Package a”,这样在执行javac -d . A.java;//这样就会在当前目录下生存a包,即目录a

jar -cvf my.jar a // 把包a创建为压缩文件my.jar

export CLASSPATH=.:my.jar //“:”是分开的意思,“.”表示当前目录,这里表示从当前目录或者my.jar中找包

public class可以被外包访问;class只能在本包中访问;

7. 内部类

在一个类A的里面重新定义一个新类B,这个类B就是内部类

一般内部类:(一般内部类可以反问外部类的私有属性)

class Outer{

  private int a =10;

  class Inner{

  public void printInfo(){

    System.out.println("a = "+a);

    }

  }

public class InnerDemo{

  public static void main(String args[]){

  Outer o = new Outer();

  Outer.Inner i = o.new Inner();

  i.printlnfo();

  }

}

静态内部类:(静态内部类的好处是可以直接访问外部类的私有静态属性)

class Outer{

  private static int a =10;

  static class Inner{

  public void printInfo(){

    System.out.println("a = "+a);

    }

  }

public class InnerDemo{

  public static void main(String args[]){

  Outer.Inner i = new Outer.Inner();//不声明外部类的情况下,直接声明内部类时,必须把内部类声明为static,且这时候的内部类只能访问外部类的static属性

  i.printlnfo();

  }

}

匿名内部类:(声明的类仅使用一次,因此不需要去继承接口,在实例化这个类)

 interface A{

  public void printflnfo();

}

public class Anony{

  public static void main(String args[]){

    testFunc(new A(){

      public void printlnfo(){

        System.out.println("hello");

      }

    });

  }

  public static void testFunc(A a){

    a.printlnfo();

  }

}

第三课 JNI (Java Native Interface)
1. JAVA调用C
Linux是用C语言写的,可以写一个APP简单调用open,read,write来访问驱动程序;
Android是用Java写的,Java怎么访问C函数?

jni.pdf P117

Android JNI知识简介
http://blog.csdn.net/linweig/article/details/5417319

Android JNI(实现自己的JNI_OnLoad函数)
http://jjf19850615.blog.163.com/blog/static/356881472013342153912/


查看"JNI field descriptors" (JNI字段描述符)
javap -s -p Var.class
JNINativeMethod的参数解析
http://carywei.iteye.com/blog/1075647
http://cs.fit.edu/~ryan/java/language/jni.html
http://blog.csdn.net/conowen/article/details/7524744


2. C调用JAVA
jni.pdf P97

http://blog.csdn.net/lhzjj/article/details/26470999

4步骤:
a. 创建虚拟机
b. 获得class
c. 实例化对象 : 获得构造方法(方法名为"<init>"), 构造参数, 调用方法
d. 调用方法 : 又分为获得方法, 构造参数, 调用方法

读取/设置类中的属性:
a. 获得属性ID
b. 读取/设置

第四课 JAVA高级应用
1. 泛型(Generics)

 在定义类的时候使用通配符来表示一个类型,在实例化的时候传入真正的类型

eg:

class Person<T> {
  private T age;

  public void setAge(T age) {
    this.age = age;
  }

  public T getAge() {
    return this.age;
  }
}

public class Generics {
  public static void main(String args[]) {
  Person<String> p = new Person<String>();
  p.setAge("3 years old");
  System.out.println(p.getAge());

  Person<Integer> p2 = new Person<Integer>();
  p2.setAge(3);
  System.out.println(p2.getAge());

  }
}

eg:函数参数的泛型使用通配符“?”

public class Generics {
  public static void main(String args[]) {
  Person<String> p = new Person<String>();
  p.setAge("3 years old");
  //System.out.println(p.getAge());
  printInfo(p);

  Person<Integer> p2 = new Person<Integer>();
  p2.setAge(3);
  //System.out.println(p2.getAge());
  printInfo(p2);

  Person<?> p3;

  p3 = p;
  //p3.setAge("4 years");//这里会出错
  p3.getAge();//这里可以正常执行

}

  public static void printInfo(Person<?> p) {
  System.out.println(p.getAge());
  }

eg:方法泛型举例 

  printInfo2(p);
  printInfo2(p2);
  printInfo2(p3);

  public static <T> void printInfo2(Person<T> p) {
    System.out.println(p.getAge());
  }

eg:子类也声明为泛型举例

class Person<T> {
  private T age;

  public void setAge(T age) {
    this.age = age;
  }

  public T getAge() {
    return this.age;
  }
}

class Student<T> extends Person<T> {
}

class Student2 extends Person<String> {
}

public class Generics {
  public static void main(String args[]) {
    Person<String> p = new Person<String>();
    p.setAge("3 years old");
    //System.out.println(p.getAge());
    printInfo(p);

    Person<Integer> p2 = new Person<Integer>();
    p2.setAge(3);
    /System.out.println(p2.getAge());
    printInfo(p2);

    Person<?> p3;

    p3 = p;
    //p3.setAge("4 years");
    p3.getAge();

    printInfo2(p);
    printInfo2(p2);
    printInfo2(p3);

    Student<Integer> s = new Student<Integer>();
    s.setAge(10);
    printInfo(s);

    Student2 s2 = new Student2();
    s2.setAge("11 years");
    printInfo(s2);

}

  public static void printInfo(Person<?> p) {
    System.out.println(p.getAge());
  }


  public static <T> void printInfo2(Person<T> p) {
    System.out.println(p.getAge());
  }

}

 eg:接口泛型举例

interface Person<T> {
  public void setAge(T age);
  public T getAge();
}

class Student<T> implements Person<T> {
  T age;
  public void setAge(T age)
  {
    this.age = age;
  }
  public T getAge() {
    return this.age;
  }
}

class Student2 implements Person<String> {
  String age;
  public void setAge(String age)
  {
    this.age = age;
  }
  public String getAge() {
    return this.age;
  }
}

public class Generics {
  public static void main(String args[]) {
    Student<Integer> s = new Student<Integer>();
    s.setAge(10);
    printInfo(s);

    Student2 s2 = new Student2();
    s2.setAge("11 years");
    printInfo(s2);

  }

  public static void printInfo(Person<?> p) {
    System.out.println(p.getAge());
  }


  public static <T> void printInfo2(Person<T> p) {
    System.out.println(p.getAge());
  }

}

 eg:受限泛型参数举例

泛型的上限 <T extends Number>   T只能是Number类或其子类

泛型的下限<T super String> T只能是String类或其父类

上限举例:

interface Person<T> {
  public void setAge(T age);
  public T getAge();
}

/* Integer, Float */
class Student<T extends Number> implements Person<T> {
  T age;
  public void setAge(T age)
  {
    this.age = age;
  }
  public T getAge() {
    return this.age;
  }
}

class Student2 implements Person<String> {
  String age;
  public void setAge(String age)
  {
    this.age = age;
  }
  public String getAge() {
    return this.age;
  }
}

public class Generics {
  public static void main(String args[]) {
  Student<Integer> s = new Student<Integer>();
  s.setAge(10);
  printInfo(s);

  Student2 s2 = new Student2();
  s2.setAge("11 years");
  printInfo(s2);

  }

  public static void printInfo(Person<?> p) {
    System.out.println(p.getAge());
  }


  public static <T> void printInfo2(Person<T> p) {
    System.out.println(p.getAge());
  }

}

 下限举例:

在声明类的地方加上<T super string>后会报错,只能在使用的时候比如在方法的参数中声明
interface Person<T> {
  public void setAge(T age);
  public T getAge();
}

class Student<T> implements Person<T> {
  T age;
  public void setAge(T age)
  {
    this.age = age;
  }
  public T getAge() {
    return this.age;
  }
}

class Student2 implements Person<String> {
  String age;
  public void setAge(String age)
  {
    this.age = age;
  }
  public String getAge() {
    return this.age;
  }
}

public class Generics {
  public static void main(String args[]) {
    Student<String> s = new Student<String>();
    s.setAge("10");
    printInfo(s);

    Student2 s2 = new Student2();
    s2.setAge("11 years");
    printInfo(s2);

  }

  public static void printInfo(Person<? super String> p) {
    System.out.println(p.getAge());
  }


  public static <T> void printInfo2(Person<T> p) {
    System.out.println(p.getAge());
  }

}

2. 反射(Reflect)

反射操作中,一切的操作都使用Object完成,类、数组的应用都可以使用Object进行接收

对于每个类,在编译后都会生成.class文件,JVM会把这些类加载进内存,并创建classobject,其有包名称、类名称、构造方法、方法、属性,可以使用三种方法来获得一个类的classobject

A、Class<?> c = Class.forName("包.类")

B、Class<?> c = new 类名().getClass();

C、Class<?> c = 类名.class

eg:根据实例化对象获得完整的包类名称

package a.b.c.d;

class Person {
  private String name;

  void setName(String name) { this.name = name; }
  String getName() { return this.name; }

};

public class Reflect {
  public static void main(String args[]) {
    Person p = new Person();
    Class<?> c1 = null;

    try {
      c1 = Class.forName("a.b.c.d.Person");
    } catch (ClassNotFoundException e) {
    System.out.println(e);
  }

  Class<?> c2 = p.getClass();
  Class<?> c3 = Person.class;

  System.out.println(c1.getName());
  System.out.println(c2.getName());
  System.out.println(c3.getName());

  int arr[] = {1,2,3};
  int arr2[][] = {{1,2,3,4},{1}};

  Class<?> c4 = arr.getClass();
  Class<?> c5 = arr2.getClass();

  Class<?> c6 = int.class;
  System.out.println(c4.getName());
  System.out.println(c5.getName());
  System.out.println(c6.getName());

  System.out.println((c4 == c5));
  System.out.println((c4 == c6));


  }
}

执行结果:

a.b.c.d.Person

a.b.c.d.Person

a.b.c.d.Person

[I     //JNI描述符

[[I

int

false

false

eg:获得类的名字有什么用呢?获得类后,可以直接实例化他,并访问其属性和方法

A:通过反射实例化对象,不用import导入包类

Person.java文件

package a.b.c.d;

public class Person {
  private String name;

  void setName(String name) { this.name = name; }
  String getName() { return this.name; }

  public Person() {
  System.out.println("Constructor of Person");
  }

  public Person(String name) {
    this.name = name;
    System.out.println("Constructor2 of Person, name is "+this.name);
  }
};

Reflect.java文件,通过反射获得内存中的classobject,在实例化后直接访问对象的属性和方法


//import a.b.c.d.Person;使用反射,不需要导入包

import java.lang.reflect.Constructor;

public class Reflect {
  public static void main(String args[]) throws Exception {
  Class<?> c = null;

  try {
    c = Class.forName("a.b.c.d.Person");
  } catch (ClassNotFoundException e) {
    System.out.println(e);
  }

  Object p = null;//因为没有import person,所有只能使用Object,其是所有类的父类

  try {
    p = c.newInstance();//调用类的无参构造方法来创建获取类的实例化对象,其向上转换
  } catch (InstantiationException e) {
  System.out.println(e);
  }

  Constructor<?> con = c.getConstructor(String.class);//通过参数类型来获得构造函数,其参数也是class类型
  Object p2 = con.newInstance("weidongshan");

  }
}

B、通过反射范围对象的方法

//import a.b.c.d.Person;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class Reflect {
  public static void main(String args[]) throws Exception {
  Class<?> c = null;

  try {
    c = Class.forName("a.b.c.d.Person");

    //c = Class.forName(args[0]);这个时候可以通过命令上次包类名称:java Reflect a.b.c.d.Person
  } catch (ClassNotFoundException e) {
  System.out.println(e);
  }

  Object p = null;

  try {
    p = c.newInstance();
  } catch (InstantiationException e) {
    System.out.println(e);
  }

  Constructor<?> con = c.getConstructor(String.class);
  Object p2 = con.newInstance("weidongshan");

  Method set = c.getMethod("setName", String.class);//获得方法
  set.invoke(p2, "123");//如果方法是静态方法,invoke的第一个参数可以是null
  set.invoke(p, "abc");

  Method get = c.getMethod("getName");

  System.out.println(get.invoke(p));
  System.out.println(get.invoke(p2));

  }
}

 eg:通过反射设置或者获得属性

import java.lang.reflect.Field;

    .........

  Field name = c.getDeclaredField("name");//获得本类中名为name的属性,所有的包括private属性

  //Field name = c.getField("name")获得公共public属性,此方法先搜索本类,在搜它实现的接口,最后在父类中搜索

  name.setAccessible(true);//设为可被外部访问,没有这一句,private属性将不可被访问

  name.set(p, "www");
  name.set(p2, "100ask");
  System.out.println(name.get(p));
  System.out.println(name.get(p2));

原文地址:https://www.cnblogs.com/liusiluandzhangkun/p/9102970.html