j2se回顾

运行Java程序.
Java程序有两种方式一种是jar包,一种是class. 运行jar,Java -jar XXX.jar运行的时候,Java.exe调用GetMainClassName函数,该函数先获得JNIEnv实例然后调用Java类Java.util.jar.JarFileJNIEnv中方法getManifest()并从返回的Manifest对象中取getAttributes("Main-Class")的值即jar包中文件:META-INF/MANIFEST.MF指定的Main-Class的主类名作为运行的主类。之后main函数会调用Java.c中LoadClass方法装载该主类(使用JNIEnv实例的FindClass)。main函数直接调用Java.c中LoadClass方法装载该类。如果是执行class方法。main函数直接调用Java.c中LoadClass方法装载该类。

然后main函数调用JNIEnv实例的GetStaticMethodID方法查找装载的class主类中

“public static void main(String[] args)”方法,并判断该方法是否为public方法,然后调用JNIEnv实例的

CallStaticVoidMethod方法调用该Java类的main方法。 
----------------------------------------------------
堆和栈是分别管理 对象和地址值的。非静态在获取实例的时候需要一个引用,(所以需要new一个对象) 而静态则不需要
native 是java用来和c/c++ 打交到的,早期java刚刚出生是c/c++横行的时候,java为了适应当时的格局,所以在jvm中开辟了一块空间特地来处理c/c++的程序。这块区域他叫做native。而native是用来处理程序和硬件打交到的区域。
栈里面是存放地址引用,堆里面的存放的是实体对象。栈的速度快,堆比较慢。
----------------------------------------------------
JAVA_HOME
D:\Java\bin
PATH
%JAVA_HOME%;%System%.....
----------------------------------------------------
设置临时的环境变量
set path="u盘上的jre文件bin文件的路径",这样path的路径就变为了临时的了,他的生命周期就在当前窗口,关闭就没有了。
javac xxx.java

class 文件不在当前文件夹下
-->set classpath f:\xxx\xx\   这样子过去,可以为当前类文件设置一个临时的路径。
----------------------------------------------------
& 过程中只要有一边为假,就为假
| 过程中只要有一边为真,就为真

&&左边为false时不参与运算
||左边为true时不参与运算

位运算,计算机专用,用于操作2进制的运算。
----------------------------------------------------
if(){}else if(){}else if(){} else  //这个虽然由多个代码块组成,但是只有一个会执行。
if 和 switch  建议只使用 switch  switch会把选择答案加载进内存,选择效率会高点。 int byte short char enum string
while(){}
do while(){}无论条件是否满足,循环体都要执行一次。
(\r \n回车) (\t制表符) (\转义字符)
标识符:

wai:for(int i;i<10;i++){
 nei:for(int j;j<10;j++){
  break wai;  //跳出外循环
 }
}
----------------------------------------------------
重载:方法名相同,参数个数不同,返回值类型不同。
数组:同一类型,固定个数的容器。

选择排序:1 第一个和后面的每一个比较,小的放前面,内圈和外圈做比较。2 内圈的起始变量是外圈的第二个。3 来个临时变量,为2个角标的引用做交换。

冒泡排序:1 相邻的2个数做比较,大的放后面。2 内圈变量是外圈长度减一。3 来个临时变量,为2个角标的引用做交换。

Arrays.sort(arr);//开发专用 ,宁外希尔排序,效率很高。

二分法查找:1 必须是有序的。
>>>右移动4位,<<<左移动4位 , 在10进制中一个数&15 相当于找到自身。

Integer.toBinatyString(-6); 十--->二进制
Integer.toOctalString(-6); 十--->八进制
Integer.toHexString(-6); 十--->十六进制
----------------------------------------------------
二维数组
引用数据类型,在堆里面,默认初始化值是null。在没有任何指向之前他就是null。
int arr[][]={{1,2,3},{4,5,6},{7,8,9}};
int sum=0;
for(int i;i<arr.length;i++){
 for(int j;j<arr[i].length;j++){
  sum+=arr[i][j];
 }
}
----------------------------------------------------
面向对象:
1 面向对象思想是一种符合现实社会中人们对问题思考习惯的思想。
2 把现实社会中复杂的事情简单化(eg:买电脑)
3 把执行者,变为指挥者(eg:买电脑)
--------------------
3 种引用类型的变量。
 1 数组。
 2 类。
 3 接口。
--------------------
局部变量和成员变量的区别
1 在类中定义的位置不同
2 在内存中的生命周期不同(堆和栈)
3 生命周期不同
4 初始化值不一样。
--------------------
匿名对象的使用场景:当对象方法或属性只有一次调用的时候就用匿名对象。
--------------------
五片内存区域:
1 寄存器。
2 本地方法区[和jni一起用]。
3 栈内存。
4 堆内存。
5 方法区[数据共享区]。
---------------------------------------------------------
面向对象:
1 封装:隐藏对象的属性和实现细节,仅对提供公共的访问和操作方式。
 构造函数:将对象初始化。每一个类都有一个默认的构造函数。
 this:表示当前对象,字节码。谁调用这个类,this就代表谁。
 {} 构造代码块,每次创建一个对象都会执行一次。而构造函数只执行一次。
  --------------------
  static: 和方法一样,存在方法区中,而方法是在被调用的时候才进栈,被static修饰的就是一直存在方法区中。
  ---1 被static修饰的,优先于对象存在。
  ---2 随着类的加载而加载,消失而消失。
  ---3 被所有成员共享。
  ---4 静态只能调用静态。非静态可以调用静态。
  --------------------
  static(类变量(在方法区中))object(实例变量(在堆中))
  方法默认存储在方法区中,而当运行的时候才在栈中。
  ---------------
  static 代码块(那他和jni有什么区别呢)
  1 随着类的加载而加载,而且只执行一次。
  2 优先于主函数执行。
  3 给类初始化。
  ---------------
  单例模式:为了保证一个工程只有一个对象。
  eg: 对象也可以用来封装数据。

  1 懒汉式。
  2 饿汉式。
  因为static 是随着类的加载而加载的,浪费内存。所以为了避免一定的空间浪费,开发中推荐懒汉式,特别是android
  单例中出现的方法,是为了[可控]
--------------------------------------------------------
2 继承:(单继承[调用的不确定性],多实现)
 1 让类与类之间产生了关系。
 2 对共性进行了抽取(属性和方法)。
 3 子类可以调用父类的属性和方法。前提是只能访问父类中public的。而且子类中使用的时候不会自动提示,但是我们手动写。
 4 在子类的所有构造函数的第一行,默认有一句 super(),他会去调用父类的构造方法。
 5 【凡是】子类继承父类,父类和子类的属性,都在子类的堆内存区当中。所以父类有的,子类就可以不用写了,写了就是内存浪费。
    特殊情况[android 自定义控件]如下:
 6 当子类重写父类了的方法之后,就会将父类的方法进行屏蔽,以后调用这个方法,都是去执行子类的逻辑,在android自定义控件中用的比较多。
 7 结论:父类的构造函数,既可以给本类对象初始化,也可以给子类对象初始化。
------------------
 继承就是不断的向上抽取。只有在其子类才有特有的功能,什么时候继承得看情况。
 this可以代表当前对象,super 代表父类空间。
 被private 修饰的不能被子类继承访问。但是子类的堆内存中有。
 当子父类中出现一摸一样的方法时,子类会覆盖(重写)父类的方法。并且子类的权限要>=父类。
 重载是函数名相同,参数不同。和覆盖不一样。
 static只能覆盖static
 在一个类中:当有参构造的出现,默认的无参构造会消失。
 继承会把父类中的所有public的功能全部拿过来。
------------------
final
被final 修饰的属性不能修改、类不能继承、方法不能重写。
在开发中常量就可以用final 来修饰,但是名称得大写。
而且在继承中,如果子类中有,默认是调用子类的,子类没有才调用父类的。
构造代码块:在super()和自己的代码之间,会调用构造代码块。
------------------
一个对象在内存中产生的过程:
1 将该对象所需的类文件加载进内存。
2 在内存中进行空间的方法区的空间分配。
3 通过new 在堆中开辟空间。
4 对象中的属性进行默认初始化。
5 调用与之对象的构造函数进行初始化。
6 通过构造函数的super调用父类中的构造函数初始化。
7 对象中的属性进行显示初始化。
8 构造代码块初始化。
9 该构造函数内部自定义内容进行初始化。
------------------
 抽象:is a  [是](多个子类继承同一个父类)
 当你描述一个事物的时候,没有足够的信息对该事物进行描述,那么这个事物对应的类就是一个抽象类。
 抽象类不能实例化。
 抽象类中的方法必须全部重写。
 抽象类中能有自己的特有方法。(接口不能)
 抽象类必须要被继承。
 子类能继承一切非 private 的方法。
 继承的本意在于抽象,而非代码的重用。
 
 -----------------
 接口:like a  [像](多个接口能被同一个类实现)
 接口里面的方法都是抽象方法。
 接口里面的常量都是静态不可被修改的。
 接口只能实现不能被new。
 接口能多实现。(解决了java的单实现的问题)
 接口能继承接口,而且接口可以【多继承】。
 接口的出现是为了定义额外的功能。
 
------------------
接口回调:
1 在Fragment类 中定义一个Test接口。
2 在Fragment类 中定义一个接口对象常量。
3 在Fragment类 中定义一个方法,为接口的引用赋值,参数是实现类的子类。
4 在MainActivity类 中实现Test接口,重写接口里面的方法,在方法里面写上自己的逻辑。
5 在TestCallBack类 中new Fragment这个对象。调用实例化接口的那个方法。参数是new MainActivity();(如果运行null,就传this吧)
-----------------
3 多态:
父类或接口的引用指向子类的实例对象。
好处:提高了代码的拓展性。
坏处:不能使用子类的特有内容。
如果想使用子类的特有功能,就得向下转型。
instanceof:向下转型的关键字,只能用于引用类型的判断。
多态-成员变量:编译运行都看左边。
多态-成员函数:编译看左边,运行看右边。
-----------------------------------------------
多线程:
进程:正在执行的任务程序。
线程:程序执行的程序。
自定义线程运行的任务都运行在run方法中。
当调用,start()方法后,线程内部,会自动执行run() 方法;
有2种方式创建线程。
1 实现Runnable接口。(这个比较好能够起拓展用的)
2 继承 Thread 类。(这个比较硬编码)
同步锁:
只要保证锁是同一个锁就不会出现线程安全的问题。

JDK 1.5 之后,Lock替代了同步,Condition替代了Object中的监视器方法。
private final Lock lock=new ReentrantLock();//创建锁对象
private Condition xiaofei=lock.newCondition();//子锁1
private Condition shencan=lock.newCondition();//子锁2
lock.lock();//加锁
xiaofei.await(); //等待
shencan.signal(); //唤醒
lock.unlock();//解锁
----------------------------------------------
eclipse 模板
方法中去掉没用的注释 java->code style ->code templates
自定义快捷键 java->Editor-> Templates
----------------------------------------------
StringBuffer(线程安全,在多线程的时候使用) StringBuilder(线程不安全,没有线程的时候,开发中建议使用这个)
字符串比较,实现 Comparable 接口,调用 Comparto()方法,会按照字典大小排序,他的返回值是0或1。
----------------------------------------------
基本数据类型,字符串转为对象 Character
toLowerCase(char ch);【指定字符串:变小写】
toUpperCase(cher ch);【指定字符串:变大写】
------------
toBinatyString 二进制
toHexString 十六进制
toOctalString 八进制
==================================================集合  记住 Collection 下的集合都能被迭代 Iterator
集合长度可变,数组长度不可变。
集合可以存储多种类型对象,数组只能存储单一类型的对象。
Iterator是Collection所有子集合共性抽取的迭代接口;

    Collection[接口]   (集合都有:增,删,改,查,的方法)                                 
     List: 链表结构:可以模仿堆栈。
   注意问题:在迭代集合的时候,/*如果需要对集合进行并发操作,会出现并发修改异常*/,我们得把Iterator 换为ListIterator。
   他的功能比 Iterator更多。(详情查看api)
    非线程安全:
    ArrayList 查询快,增删慢。
    LinkedList 增删快,查询慢。 【可以用来模仿堆栈 addLast(),removeFlast()】
    
    /*线程安全*/,在多线程的时候使用:
    Vector 底层是数组结构。他迭代的时候可以用枚举接口, Enumeration 来迭代。因为枚举在的时候还没有集合框架。
  Set:  集合结构:可以用来去重。
   HashSet 无序的。存储时速度巨快,因为底层是根据哈希算法来实现的。但是不关心顺序,并且唯一。需要查询hashCode() 和equers()
    自定义对象(往哈希表中存储数据的时候)要重写 equals(),HashCode()  方法。才能做比较。
    自定义对象(如果想让对象具备比较大小的功能,按照自然顺序排序,必须要实现 Comparable接口 )
    eg:/*牛逼的equers()方法
     public boolean equers(Object obj){
      if(this==obj){//比较地址
       return true;
      }
      if(!(obj instanceof Student)){
       throws new ClassCastException("类型不匹配,无法比较");
      }
      Student stu=(Student) obj;
      return this.name.equals(stu.name) && this.age==stu.age;
     }
     */
   TreeSet:
    排序方式1:
     使用元素的自然顺序进行排序。他保证数据的唯一性,是在自定义对象中实现 Comparable接口 重写compareTo()看返回值是否为0,为0就是重复的元素。
    排序方式2:
     定义一个比较器,让对象一初始化就具备比较功能,实现 Comparator 接口。重写 compare()方法,相等返回0;
     如果需要先按照字典排序又要按照长度排序,那么就得在compare()里面继续调用 compareTo() 方法了。
     实现原理是二叉树比较法。就像二分查找法一样。
     person p=(person)o;
     int temp =this.age-p.age;
     return temp==0?this.name.compareTo(p.name):temp;
   LinkedHashSet:
    有序且去重复的列表:
  
  范型:
   上边界: ? extends person (传递进来的参数只能为 person的本身或者子类型)
   下边界: person super ? ()
  泛型类:
  省去了曾经的强转和类型转换异常的麻烦。(将泛型定义在类上,使用者只需要在使用这个类的时候传入泛型就可以了)
  具体什么类型由使用者确定。
  eg: public Util<T>{   //使用方只需要   这样使用    Util<Person> u=new Util<Person>
    private T t;//        u.setT(new Person());
    public void setT(T t){//     u.getT();
     this.t=t;
    }
    public T getT(){
     return t;
    }
   }
  
  泛型方法:在不确定方法的参数的时候,需要什么类型自己传递 (基本数据类型,或者对象类型,都可以)
  eg: public <W> void show(W w){
    System.out.println("w:"+w);
   }
  
  泛型接口:也是传入的参数不确定的时候使用的。
  eg:public interfrace inner<V>{
    public abstract void show(V v);
   }
   class innerImpl<C> implements inner<C>{
    public void show(C c){
     System.out.println("c:"+c);
    }
   }
   
   main(String[] args){
    new innerImpl<Integer>().show(new Integer(3));
    new innerImpl<String>().show(new String("ok"));
   }
  fore() 循环,不操作角标,能操作数组和 Connection集合;
   
 Map(Key,Value):
  key不能重复;
  取值有2种方式:
   1 map.keySet 得到所有key的集合
   2 map.entrySet 得到所有key和value的集合  (entry 实体对象)
   
  
  1.0 Hashtable 线程安全,key value不允许为空(和Vector一个时代的)
  1.2 HashMap   线程不安全,key value允许为空【如果是自定义对象,在迭代的时候要去除重复的key,可以参阅 250行牛逼的equers()方法】
   TreeMap   底层是二叉树实现的,如果想让自定义对象也具有比较性,必须实现 Comparable接口,查询 compareTo();
   LinkedHashMap 有序结构的链表集合(内部模拟了堆栈的实现)
   //Properties 他也是键值对的属性集,重要的是他能持久化这个集合,用于IO流读取,他的父类是HashTable
  
 专门操作集合的工具类:
 Collections   eg:详情查看api;  工具类中有,synchronizedCollection(),List,Map可以将非同步的集合转为同步的集合。
 Arrays    eg:详情查看api; asList(int[] i)数组转集合。但是有些方法是不能用的。因为集合是固定的。不能做增删操作。
          toArray()集合转数组。定义类型必须一致。
    
  可变参数: ... 可以替代很多个数的数组,前提是必须放在参数列表的最后面。
 
其他api:
 System: 有一个很有意思的api, System.getProperties()他能返回这个整个环境和工具的信息的集合。
 还可以通过集合里面特定的key值,可以在不同平台下都能使用的特殊功能符号。
 
 Runtime:这是一个底层由单例模式完成的运行时类。 通过Runtime.getRuntime()可以得到他的对象。详情查看 api
 eg:启动qq  Runtime.getRuntime().extc("qq.exe");{这里面,写的的是Dos命令}
 
 Math: abs()绝对值 , ceil 天花板 floor地板 round四舍五入 Max最大 Min最小 pow幂运算,... 正旋余弦 更多查看api

 
IO流:用来处理设备间的数据传输,分输出流和输入流。{只要对象一创建就有文件。如果已经存在会被覆盖}
 使用完之后一定要记得关闭流对象。而且得放在finally中,而且这个流对象还得做非空判断,防止对象没有创建成功,报null异常。
由于操作系统不同,有的时候\r\n 不好使,所以我们使用 System.getProperty("line.separator");
字节流:
 InputStream OutputStream: (看顶层,用底层)
 FileInputStream
 FileOutputStream
 字节流可以直接将内容写到目的地,不需要临时存储就能操作文件,比字符流少了走缓冲区这一步。他是直接操作字节的。
 装饰模式:
 BufferedInputStream 对已有的对象提供了额外的功能,还不用对源对象进行修改,避免了继承的臃肿。
 BufferedOutputStream
 转换流:(其实我想说:他也是代理模式么?)
 InputStreamReader(new InputStream()):字节转字符,将内存看不懂的字节转为可以看懂的文字。
 OutputStreamWriter(new OutputStream()):字符转字节,将看的懂的文字转为内存为看不懂的字节。
 

字符流:(字节流+编码表)
 Reader Writer:
 
 FileWriter FileReader
 文件操作流。
 对文件进行续写 new FileWriter("demo.txt",true);
 在内存中定义高效的缓冲区:(一般获取内存中的速度远比直接获取目的地的数据快高效)
 BufferedReader(new FileReader());  BufferedWriter(new FileWriter());
 装饰模式:
 [其实BufferedReader 这种方式是典型的装饰模式的应用:对已有的对象提供了额外的功能,还不用对源对象进行修改,避免是继承的臃肿]
 BufferedReader(new FileReader());
 LineNumberReader(new FileReader());
 
IO流4步曲
 1 明确源和目的 I  O
 2 是否纯文本 FileReader
 3 明确设备
 4 是否需要高效 BufferReader
 
 转行流:
 InputStreamReader(),指定编码表 InputStreamReader(is,"UTF-8");
 OutputStreamWriter(),指定编码表 OutputStreamWriter(os,"UTF-8");
 
File 类:
 File.separator 名称分隔符,在任何环境下都能使用,linux和windows下都能识别,他会自动转换
 File.getTotalSpace() 总大小
 File.getFreeSpace() 剩余空间
 File.deleteOnExit();退出系统的时候会自动删除文件(所以在我们创建文件之后可以立马写这句话)
 File.isFile() 是否为文件
 File.isDirectory() 是否为文件夹
 file.list(new filter());文件过滤器
 file.listFilse(new filter());文件夹过滤器
 
SequenceInputStream 合并流:
public static void main(String[] args) throws IOException {
  将多个流进行逻辑串联(进行合并,变成一个流,操作起来很方便,因为多个源变成了一个源)
  FileInputStream fis1 = new FileInputStream("tempfile\\seq_1.txt");
  FileInputStream fis2 = new FileInputStream("tempfile\\seq_2.txt");
  FileInputStream fis3 = new FileInputStream("tempfile\\seq_3.txt");
  
  ArrayList<FileInputStream> v = new ArrayList<FileInputStream>();
  v.add(fis1);
  v.add(fis2);
  v.add(fis3);
  Enumeration<FileInputStream> en = Collections.enumeration(v);
  SequenceInputStream sis = new SequenceInputStream(en);
  //创建目的。
  FileOutputStream fos = new FileOutputStream("tempfile\\seq_4.txt");
  byte[] buf = new byte[1024];
  int len = 0;
  while((len=sis.read(buf))!=-1){
   fos.write(buf,0,len);
  }
  fos.close();
  sis.close();
 }
 RandomAccessFile:多线程下载专用流。
 seek(8); 能随机操作指针的方法,可以开启多个线程同时操作这个对象。达到多线程下载。
 
 从看不懂到看得懂解码,从看的懂到看不懂,编码。


文件加密:
 public static void main(String[] args) throws IOException {
  BufferedInputStream bis = new BufferedInputStream(new FileInputStream("copy4.mp3")); // 创建流对象,并给流对象加上缓冲区
  BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy5.mp3"));

//  byte[] buf=new byte[1024]; 操作字节的时候,自定义的缓存数组就不要了,会导致垃圾产生
  int b=0;
  while ((b = bis.read(/*buf*/)) != -1) {
   bos.write(b ^ 111);//这个11 就是密钥
  }
  bis.close();
  bos.close();
 }

网络编程:
UDP:
不需要建立连接速度快。数据大小限制在64k之内,无连接,不可靠协议。

TCP:
需要建立连接,经过3次握手,可以进行大数据传输,是可靠协议,但效率会稍低。

TCP协议,多线程上传文件,源码
public class UploadPicClient {
 public static void main(String[] args) throws UnknownHostException, IOException {
  if(args.length!=1){
   System.out.println("请指定文件");
   return;
  }
  File file = new File(args[0]);
  if(!(file.exists() && file.isFile())){
   System.out.println("该文件不存在,或不是正确的文件,重新指定");
   return;
  }
  if(!(file.getName().endsWith(".jpg") || file.getName().endsWith(".gif"))){
   System.out.println("文件扩展名必须是jpg,或者而是 gif。");
   return;
  }
  if(file.length()>=1024*1024*2){
   System.out.println("文件过大,重新选择,");
   return;
  }
  Socket s = new Socket("192.168.1.100",10006);
  FileInputStream fis = new FileInputStream(file);
  OutputStream out = s.getOutputStream();
  byte[] buf = new byte[1024];
  int len = 0;
  while((len=fis.read(buf))!=-1){
   out.write(buf,0,len);
  }
  //告诉服务器端,发送数据完毕,发送一个结束标记。
  s.shutdownOutput();
  InputStream in = s.getInputStream();
  byte[] bufIn = new byte[1024];
  int lenIn = in.read(bufIn);
  String info = new String(bufIn,0,lenIn);
  System.out.println(info);
  fis.close();
  s.close();
 }
}

public class UploadPicServer {
 public static void main(String[] args) throws IOException {
  //服务端,接收客户端发送过来的图片数据。 进行存储后,回馈一个 上传成功字样。 多用户的并发访问。
  ServerSocket  ss = new ServerSocket(10006);
  while(true){    
   Socket s  = ss.accept();
   
   new Thread(new UploadThread(s)).start();
  }
//  ss.close(); 
 }
}

public class UploadThread implements Runnable {
 private Socket s;
 public UploadThread(Socket s) {
  super();
  this.s = s;
 }
 @Override
 public void run() {
  String ip = s.getInetAddress().getHostAddress();
  System.out.println(ip+"......connected");
  try{
  //读取数据。网络。
  InputStream in = s.getInputStream();
  File dir = new File("c:\\mypic");
  if(!dir.exists())
   dir.mkdir();
  int count = 1;
  File file = new File(dir,ip+".jpg");
  while(file.exists()){
   file = new File(dir,ip+"("+(count++)+").jpg");
  }
  //目的:文件
  FileOutputStream fos = new FileOutputStream(file);
  byte[] buf = new byte[1024];
  int len = 0;
  while((len=in.read(buf))!=-1){
   fos.write(buf,0,len);
  }
  OutputStream out = s.getOutputStream();
  out.write("上传成功".getBytes());
  fos.close();
  s.close();
  }
  catch(IOException e){
  }
 }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值