Java高新技术1(eclipse使用技巧,享元设计模式,枚举类型)

 

1.IDE概述:

1.IDE->integrated development environment(集成开发环境)

   NetBeans: NetBeans包括开源的开发环境和应用平台 Jcreator

2.Ecliplse图形化界面->会使用javaw.exe启动

3.MyEclipse与Eclipse: MyEclipse扩展了Eclipse功能,是一个插件 Myeclipse的核心就是eclipse, 只不过Myeclipse在此基础上增加了许多的插件, 使用起来更加的方便 更详细了解两者区别于联系:http://www.cnblogs.com/panjun-Donet/articles/1156895.html

2.明确eclipse中的一些概念:

3.Eclipse
  ①工程(Project):
    一般来说一个相对独立的项目就是
一个工程,一个项目中
    涉及的多个java文件,资源文件等用一个工程进行分类管理.

  
  为什么要使用Project
?

   在不使用工程管理的情况下,如果一个项目中包括多个java源文件,
    编程人员需要精心维护这些源文件之间,以及源文件与其它文件的
    目录关系,需要逐一编译这些源文件,需要手工启动运行编译后的结果

    如果将一个程序的所有源文件用一个工程来组织,开发工具能对所有源文件集中
    管理,记住每个源文件的位置和相互关系.工程中有哪几个源文件.启动类是哪个
    启动参数设置等配置信息都在工程中都记录

    之前一直在用cmd命令来compile,execute,那是因为同时操作的源文件,类等很少
    还能手动管理,试想上千个呢? 如果不分类管理,那将是一件很痛苦的事.
 
  ②WorkSpace(工作空间/工作台)
    一个workspace可以包含多个Project,一个workspace保留了eclipse的一套环境选项的配置
    对工作间配置将影响其下的所有工程
    例如:所使用的javac和java命令是哪个JDK版本里的等等.
       
    如果要为eclipse再配置一套环境选项,可以在创建一个workspace
    
    每个人都有自己的使用习惯(快捷键配置,窗体等等)形成自己的工作间

    新建一个工作间:File->New->SwitchWorkspace->

Other 新建的工作间是空的,没有任何工程

 

③工作集:(百度知道) 如果您有很多eclipse工程,举个例子来说: 您eclipse的workspace有10个工程,5个是A项目相关的, 5个是B项目相关的,如果10个工程都全部显示, 比较多,看着不方便,您就可以建一个working set, 对工程进行分组。您建一个working set A,把A相关的工程都加入到working set A, 再建一个woring set B,把B 相关的工程都加入到working set B。 这样的话您选择working set A的时候,就只显示A项目的工程, 选择working set B的时候,就只显示B项目的工程。

④新建项目->新建类(会同时生成.java和.class文件,两者名称相同) 字体看着很不爽调整代码的字体: 窗口(window)->首选项(Preference)->General(常规)->Appearance(外观)->Colors and Fonts(颜色和字体)->java编辑器文本字体
    快捷键:
     General下的Keys(键)进行相应调整
  ⑤透视图(PersPective)
    就是不同的若干个小窗口(视图)的集合(Debug透视图等等)

3.配置eclipse编译与运行环境

1.配置编译环境和运行环境 窗口(window)->首选项(Preference)->java->编译器 ->
已安装jre  进行相同JDK版本配置,也可以导入外部JDK
 如果在运行一个工程下类文件发生:
  java.lang.UnsupportedClassVersionError:Bad version number in .classfile
 例如:把1.7版本的javac.exe编译后的类文件用1.5的版本java.exe运行
 
 高版本的java.exe可以运行低版本的javac.exe编译的程序
 低版本的java.exe不可以运行高版本的javac.exe编译的程序
 这也就是向下兼容

eclipse工作台(workspace)中的所有工程(project)继承工作台配置,其中某个工程可以覆盖工作台配置
 java的继承和多态思想- -!!!

2.模板(偷懒必备)
  窗口(window)->首选项(Preference)->java->editor->templates
  

3.在eclipse当前工作台中导入已有工程
  ①.把该project所在的文件夹拷贝到当前workspace下

  ②.project
->import->General->Existing Projects into Workspace

4.build path
原文地址:http:
//blog.csdn.net/cheney521/article/details/8526414

①source: source folder: 存放.java源文件的根目录; output folder: 源文件编译输出的存放.class文件的根目录; 纯“java project“中:一般把"src" 设置为source folder,把bin设置为output folder;
  ②Libraries:
    是用来管理类库的,包括外部类库的添加和删除
    很多的.

class--打包->.jar---打包-->Libraries
 
可以Add External Jars,也可以Add Library-->User Library->New->根据自己需要,在自己的library增加.jar,该动作会影响当前工程

的classpath
 ③Order and Export的up和down
     调用优先级的问题,越在上边调用优先级越高,
      例如:
     在同包同类名的情况下,将优先从上到下执行搜索调用;
     打勾与不打勾的区别在于导出jar包时是否将这个库的内容也打包到jar中,
      勾为包含,不勾为不含。

4.享元设计模式(Flyweight Pattern):共享对象,节约内存

/*
享:共享
元:单元
举例装箱:
  -128~127这些数据太过于常用,也就是说经常在程序出现
  如果我装箱,每个都new一个对象,相当浪费内存
  因此可以这样干:
  内部建立一个长度为256的引用数组,数组中的每个引用变量指向一个
  Integer对象(-128~127),当装箱时,检查是否在-128~127范围内,是
  使用cache数组中的对象.
*/

 

5.枚举类型

1.枚举概述:

/*
  枚举:一一列举
  说明为有穷个,可以列举出来.例如:工作日(周日~周六),颜色(红,黄,.....),字体大小(1,2..)
 为什么要有枚举?
   问题:要定义星期几或性别的变量,该怎么定义?假设用1~7分别表示星期一到星期日,
        但有人会写成int weekday=0,也就是说不统一;
 枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则编译器就会报错(一种约束/限定)
   枚举优点:
      枚举可以让编译器在编译时就可以控制源程序中填写的非法值
      普通变量的方式在开发阶段无法实现这一目标
 */

2.用普通类模拟枚举功能:

class WeekDay{
   private WeekDay(){}//不允许外部new对象,只能使用我内部提供的
   public static final WeekDay SUN=new WeekDay();//外部不能创建对象那只能定义成static
   public static final WeekDay MON=new WeekDay();
   public static final WeekDay TUES=new WeekDay();//这里为了简化代码,只到星期二
   
  public String toString(){//为了打印结果的友好
     return this==SUN ? "星期日" :(this==MON ? "星期一" : "星期二");
   }
  
   public static void main(String[] args){
    WeekDay wd=WeekDay.TUES;//你只能取MON,SUN,TUES其它不能取,否则编译期不能通过
    System.out.println(wd);//星期二
  }
 
 }

3.对于以上添加nextDay方法:

class WeekDay{
   private WeekDay(){}//不允许外部new对象,只能使用我内部提供的
   public static final WeekDay SUN=new WeekDay();//外部不能创建对象那只能定义成static
   public static final WeekDay MON=new WeekDay();
   public static final WeekDay TUES=new WeekDay();//这里为了简化代码,只到星期二
   
   public WeekDay nextDay(){
     
     return this==SUN ? MON :(this==MON ? TUES :SUN);//让TUES的next为SUN
   }
       
   public String toString(){//为了打印结果的友好
     return this==SUN ? "星期日" :(this==MON ? "星期一" : "星期二");
   }
  
   public static void main(String[] args){
    WeekDay wd=WeekDay.TUES;//你只能取MON,SUN,TUES其它不能取,否则编译期不能通过
    System.out.println(wd);//星期二
  }
 
 }

4.采用匿名内部类的形式完成nextDay功能(多态)

abstract class WeekDay{//原类为抽象,也不能创建对象     
private WeekDay(){}
       public static final WeekDay SUN=new WeekDay(){
          public WeekDay nextDay(){
              
           return MON;//MON为静态随着类的加载而加载      
              
          }
        };
       public static final WeekDay MON=new WeekDay(){
           public WeekDay nextDay(){
                  
               return TUES;//MON为静态随着类的加载而加载      
                  
           }
           
       };
       public static final WeekDay TUES=new WeekDay(){
           public WeekDay nextDay(){
                  
               return SUN;//MON为静态随着类的加载而加载      
                  
            }
           
       };
       
       public String toString(){
         return this==SUN ? "星期日" :(this==MON ? "星期一" : "星期二");
       }
       
public abstract WeekDay nextDay();
              
     
public static void main(String[] args){
        WeekDay wd
=WeekDay.TUES;
        System.out.println(wd);
        System.out.println(wd.nextDay());
      }
    
}
/*
该思想很好的把nextDay中的判断融入到了匿名子类对象中,省去繁琐的判断
*/

6.深入Java枚举:主要参考博文:http://www.cnblogs.com/frankliiu-java/archive/2010/12/07/1898721.html

1.java中枚举的定义:

enum Colour{  //短小精悍
    
    RED,BLUE;
}  
/*
java语言规范中枚举的格式:
   An enum declaration has the form: 
  EnumDeclaration:
    ClassModifiersopt enum Identifier Interfacesopt EnumBody

   EnumBody:
    { EnumConstantsopt ,opt EnumBodyDeclarationsopt }
*/

通过反编译看看编译器对这孩纸干了什么:

//反编译后:
final class Colour extends java.lang.Enum<Colour> {//继承了Enum,因此可以使用其中一些方法
  public static final Colour RED;

  public static final Colour BLUE;
 /*内部定义了values和ValueOf方法*/
  public static Colour[] values();
    Code:
       0: getstatic     #1                  // Field $VALUES:[LColour;
       3: invokevirtual #2                  // Method "[LColour;".clone:()Ljava/
lang/Object;
       6: checkcast     #3                  // class "[LColour;"
       9: areturn

  public static Colour valueOf(java.lang.String);
    Code:
       0: ldc_w         #4                  // class Colour
       3: aload_0
       4: invokestatic  #5                  // Method java/lang/Enum.valueOf:(Lj
ava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
       7: checkcast     #4                  // class Colour
      10: areturn

  /*静态代码块中执行的内容*/
  static {};
    Code:
      /*
      下面几句相当于干了这些事:
   Colour RED=new Colour("RED",0);
   Colour BLUE=new Colour("BLUE",1);
      在Colour构造函数中使用(super("RED",0);)了父类的构造函数: protected Enum(String name,int ordinal)
      name - - 此枚举常量的名称,它是用来声明该常量的标识符。
      ordinal - - 枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。
      */
       0: new           #4                  // class Colour
       3: dup
       4: ldc           #7                  // String RED
       6: iconst_0
       7: invokespecial #8                  // Method "<init>":(Ljava/lang/Strin
g;I)V
      10: putstatic     #9                  // Field RED:LColour;
      
      13: new           #4                  // class Colour
      16: dup
      17: ldc           #10                 // String BLUE
      19: iconst_1
      20: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      23: putstatic     #11                 // Field BLUE:LColour;
      
      
      
      /*创建一个数组对象相当于:new Colour[2]*/
      26: iconst_2
      27: anewarray     #4                  // class Colour
      
      
      
      /*将RED和BULE存入到创建的数组中,其实就是数组中的引用变量分别指向这两个对象*/
      30: dup
      31: iconst_0
      32: getstatic     #9                  // Field RED:LColour;
      35: aastore
      
      36: dup
      37: iconst_1
      38: getstatic     #11                 // Field BLUE:LColour;
      41: aastore
       
      42: putstatic     #1                  // Field $VALUES:[LColour;
      45: return
}
/*
enum Colour被解释成:
  final class Colour extends java.lang.Enum<Colour>
自定义的枚举类会继承Enum中的方法

 public static final Colour RED;

 public static final Colour BLUE;
 原来枚举中定义的是引用类型->和刚才的自定义类中的成员如出一辙

public static Colour[] values();
  静态方法,返回一个包含全部枚举值的数组
public static Colour valueOf(java.lang.String);
  内部调用了继承的valueOf(Class,String)方法,返回
  返回带指定名称的指定枚举类型的枚举常量。
  名称必须与在此类型中声明枚举常量所用的标识符完全匹配。(在这里只能传入"RED"和"BLUE")
  (不允许使用额外的空白字符。) 


好啊,书写的挺简单,其实编译器帮你干了好多事,不用自己去自定义枚举,简化了书写

*/

2.枚举中的构造方法:

enum Colour{
    
    RED,BLUE(2);//必须位于所有成员之前,其实RED相当于RED(),BLUE(2)会调用构造方法Colour(int x)
    private Colour(){}
    private Colour(int x){
        System.out.println("x="+x);
    }
}
import static java.util.Arrays.toString;//该语句只导入了Arrays中的toString方法,因此下面还需要导入Arrays类
import java.util.Arrays;
public class EnumTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
         System.out.println(WeekDay.TUES.nextDay());
    Colour c=Colour.RED;
    System.out.println(c.toString());
    System.out.println(Colour.valueOf("BLUE"));//返回一个Colour对象
    System.out.println(Arrays.toString(Colour.values()));
    
    }
    
}

Enum

enum Colour{  
    
    RED,BLUE(2);
    private Colour(){}
    private Colour(int x){}
}  

//反编译看出其调用方式:
   21: invokespecial #11                 // Method "<init>":(Ljava/lang/String;II)V
   //相当于调用了private Colour(Stirng ,int ,int)
   //一个int值代表枚举元素的序号,另一个就是x值

3.带有抽象方法的枚举:枚举其实就是一个final class,其中可以有抽象方法

/*带有抽象方法的枚举*/
enum TrafficLamp{//enum前面不能用abstact修饰
    RED(4){
         public TrafficLamp nextLamp(){
             return  GREEN;
         }
    },
    /*
    
     相当于 public static final RED=new TrafficLamp("RED",0,4){
        public TrafficLamp nextLamp(){
             return GREEN;
         }
     };
     枚举中的匿名子类对象 ,这一点我们可以从编译后的class文件中看出:
     TrafficLamp$1.class
     TrafficLamp$2.class
     TrafficLamp$3.class
     */
    YELLOW(2){
        public TrafficLamp nextLamp(){
             return  RED;
         }
    },
    GREEN(5){
        public TrafficLamp nextLamp(){
             return  YELLOW;
         }
    };
    private int time;//设置一个灯亮的时间
    private TrafficLamp(){}
    private TrafficLamp(int time){
     this.time=time;
    }
    public abstract TrafficLamp nextLamp();//父类的抽象方法
}
枚举中一旦有有抽象方法,每个元素都必须实现该方法.
因为:
一旦含有抽象方法,TrafficLamp为abstract class,本身不能new对象,只能通过子类来new对象
那么枚举中的每个元素必须采用匿名内部类的方式实现该抽象方法.

含有抽象方法的枚举会被编译器解释为:
 abstract class TrafficLamp extends java.lang.Enum<TrafficLamp>

4.枚举与单例

//枚举只有一个成员(相当于只有一个对象),就可以做为一种单例的实现方式.
/*
单例设计模式*/
enum SingleInstance{
    REF;
}

5.最后一点枚举类型可以在switch(枚举类型) 中使用(套用原作者):

/*
回想Switch(变量) :该变量的类型可以是::byte ,short,char,int,以及JDK 1.7最新特性添加一个String
现在多了个枚举类型
*/
Colour c=Colour.RED;  
switch(c){
      case RED:System.out.println("红色");break;//这里的case后面的常量简写为RED,而没有写Colour.RED,说明编译器根据c推断枚举常量类型
      case BLUE:System.out.println("蓝色");break;     
    }
posted @ 2013-07-17 22:34  伊秋  阅读(738)  评论(0编辑  收藏  举报