这篇博客主要有以下知识点:Myeclipse中Junit的使用、静态导入、枚举、单例设计模式(饿汉式和懒汉式)
知识点一:Myeclipse中Junit的使用(有四个类Person.class、PersonTest.class、PersonTest1.class、PersonTest2.class)
先写个Person类:
public class Person {
public void run()
{
System.out.println("run.....");
}
public int[] array()
{
return new int[]{1,2};
}
public int speak()
{
return 12;
}
public void eat()
{
System.out.println("eat.....");
}
}
PersonTest:
为Person类写两个测试方法testRun和testEat,需要有@Test注解,并且要引入相关包。我们看到在开头和结尾有两个方法,分别是bfore和after(方法名可以自定义),它们的注解分别是@Before和@Afterj,这两个方法会在每个测试方法运行前后都执行一次,用来给测试方法中所需要的资源进行初始化和释放资源,例如下面可以将pp的初始化放在before,释放放在after中。而不必在每个测试方法中都写Person pp=new Person(),如果有几百个测试方法,那么再这样写就是灾难。所以放在@Before注解的方法中最合适了,最后在@After注解的方法中释放资源即可
public class PersonTest1 {
@BeforeClass
public static void beforeClass()
{
System.out.println("beforeClass");
}
@Test
public void testRun(){
Person p=new Person();
p.run();
}
@Test
public void testEat()
{
Person pp=new Person();
pp.eat();
}
@AfterClass
public static void afterClass()
{
System.out.println("afterClass");
}
}
PersonTest2:
断言:用于测试需要测试的类的真实值是否是自己期望的。下面列举了Assert类中的assertEquals和assertArrayEquals方法,他们的参数第一个是期望的值,第二个参数是被测试方法的返回的实际的值.
public class PersonTest2 {
@Test
public void testSpeak(){
Person pp=new Person();
Assert.assertEquals(12, pp.speak());//测试speak这个方法运行的结果是不是你想要的,即是否是12,
}
@Test
public void testArray()
{
Person pp=new Person();
//测试某个方法返回的数组是否是第一个参数中数组相同,即是否是你想要的,
Assert.assertArrayEquals(new int[]{1,2}, pp.array());
}
}
知识点二:静态导入
就是说一个类中的某个静态方法在另外一个类中频繁使用时,就可以将其静态导入(例如Arrays这个类,它里面全是静态方法,如果在另外一个类中频繁调用Arrays.asList()方法,我们就可以在所谓的“另外一个类”中静态导入这个Arrays这个类的某个或全部的静态方法)
格式:import static day1.itcast.demo.speak;
day1.itcast.demo.speak只是个例子,意思是day1.itcast包下的demo类中的speak方法
知识点三:枚举(用到了Junit)
先举个例子说明枚举是怎么来的:
枚举是1.5以后的新特性,枚举的作用:一些函数在运行时,需要传入的参数不是任意的,而是一定范围内的,下面看个例子。下面的方法是jdk1.5以前的解决方法
public class EnumDemo {
/*
* 枚举是1.5以后的新特性
* 枚举的作用:一些函数在运行时,需要传入的参数不是任意的,而是一定范围内的,下面看个例子。
* 下面的方法是jdk1.5以前的解决方法
* */
/*1
这个method方法要求传入的参数是自定义Argument类的类型,我们要传入Argument类型的参数
想到的是Argument类的一个实例就行了,这个实例通常会Argument arg=new Argument();
但是如果Argument类的构造函数被private呢,具体看测试方法testMethod()
*/
public void method(Argument arg)
{
System.out.println("枚举举例");
}
//2
@Test
public void testMethod()
{
//下面被注释的部分是不允许的,因为Argument被私有化了
//Argument arg=new Argument();
//为了解决这个问题,我们可以在Argument类中先定义好一些Argument的几个实例,
//然后直接调用即可,看Argument类中具体代码
Argument arg=Argument.B;
method(arg);
}
//5看下利用枚举是怎么解决这个问题的
public void method2(Argument1 arg)
{
System.out.println("枚举举例");
}
//6看枚举类,就知道很简单了,不做赘述
@Test
public void testMethod2()
{
Argument1 arg=Argument1.A;
method2(arg);
}
}
//4
class Argument{
//将Argument类进行私有化,防止外界创建对象
private Argument(){};
/*
* 如果外界想要Argument的对象怎么办?外界不能实例化但是自己可以实例话
* 所以在自己内部实例化几个公有的static的Argument的实例,
* 这样即可提供给外界使用
*
* */
public static final Argument A=new Argument();
public static final Argument B=new Argument();
public static final Argument C=new Argument();
public static final Argument D=new Argument();
}
enum Argument1{
A,B,C,D
}
上的例子是说明枚举是怎么来的,下面具体看枚举的分析:
代码:(主要讲三点)
public class EnumAbstract {
第一点
public void method(Grade grade)
{
String value=grade.getValue();
System.out.println(value);
}
@Test
public void testMehod()
{
method(Grade.A);
}
/*
下面看具体的一个枚举实例:我们自定义了一个枚举,希望外界使用这个枚举中的某个值时,能获取这个值所代表的具体值,怎么做?看下面分析:
这个枚举中有5个枚举对象,有String类型的属性value(用于封装每个枚举值的数据),私有的构造方法(注意这个构造方法必须是私有的,
如果是public,那么外界就可以修改枚举值了,所以定义成私有的),供外界获取枚举值的方法getValue;很明显这样设计一个枚举,
就可以在外界通过getValue获取每个枚举值所对应的具体值了。
小分析:通常可能看到的枚举是这样的:enum WeekDay{SUN,MON,THU,WED,THR,FRI,SAT;}
而下面的每个枚举对象都是形如这样的A("100-90"),如果不这样定义该怎么定义,
因为里面已经显示的写了一个带参数的构造方法了啊(WeekDay中没有写是因为有了默认的构造方法了,所以没有像A("100-90")这样写,而是SUN()),
A,B...都是枚举的一个个具体实例,既然有个带参数的构造方法,那么在定义一个个实例时,是不是要给它具体实例化(形如new Person(12))
* */
enum Grade{
A("100-90"),B("89-80"),C("79-70"),D("69-60"),E("59-0");
private String value;
private Grade(String str)
{
this.value=str;
}
public String getValue()
{
return value;
}
}
///第二点
public void method2(Grade2 grade)
{
String value=grade.getlocalValue();
System.out.println(value);
}
@Test
public void testMethod2()
{
method2(Grade2.A);
}
/*
再看一种情况:带抽象的枚举。上面的枚举如果拿给另外一个程序员用,
他想要的成绩是这样的A-->优,B-->中,C-->良,D-->及格,E-->差,但是又想保留原来那中数字格式的
怎么做?这就用到了抽象方法了
* */
enum Grade2{
A("100-90"){
@Override
String getlocalValue() {
return "优";
}
},
B("89-80"){
@Override
String getlocalValue() {
return "中";
}
},
C("79-70"){
@Override
String getlocalValue() {
return "良";
}
},
D("69-60"){
@Override
String getlocalValue() {
return "及格";
}
},
E("59-0"){
@Override
String getlocalValue() {
return "差";
}
};
private String value;
private Grade2(String str)
{
this.value=str;
}
public String getValue()
{
return value;
}
//在枚举中定义一个抽象方法,具体实例枚举的一个个对象时,实现这个方法即可
abstract String getlocalValue();
}
///第三点
//Enum类的一般方法使用,所有的枚举类都是Enum类在子类,即使没有明确的写extends Enum
@Test
public void testGeneral()
{
//获取枚举中具体某个对象的值,结果是"100-90"
System.out.println(Grade.A.value);
//获取具体枚举对象的名称;结果是A
System.out.println(Grade.A.name());
//获取枚举对象的序数,结果是0
System.out.println(Grade.A.ordinal());
/*
枚举的valueOf方法,作用:将某个字符串转换成自定义的枚举对象
举个例子:在网页上我们可能填过表单(就是注册用户是要填写信息的表单,什么姓名、年龄,性别等)
就拿性别来说,我们填写好之后提交数据到服务器,服务器会将性别这个字符串中的值(男或女),转换成服务器端自定义枚举的一个对象,
如果自定义枚举中有这个值,那么运行正常,如果没有就会报错,可能会提示用户没有选择性别这一项,
* */
//String str="K";//会报错,因为Grade中没有这个对象
String str="B";
Grade gg=Grade.valueOf(str);
System.out.println(gg.name());
//获取枚举中的对象,返回的是一个枚举数组,作用:我们通常不知道别人定义的枚举中有哪些对象时,
//就可以这样查看别人定义的枚举中有哪些枚举对象了
Grade[] grades=Grade.values();
for(Grade g:grades)
{
System.out.println(g.name());
}
}
}
总结:
枚举类也是一种特殊形式的java类
枚举类中声明的每一个枚举值代表枚举类的一个实例对象
与java中的普通类一样,在声明枚举时,也可以声明属性、方法和构造方法,但枚举类的构造函数必须为私有
枚举也可以实现接口、或继承抽象类
Jdk5中扩展了switch语句,它除了可以接收int、byte、char、short这四种基本数据类型外,还可以接收一个枚举类型
如枚举类只有一个枚举值,测可以当做单例设计模式使用
知识点四:单例设计模式
解决一个类在内存中存在一个对象。
想要保证对象的唯一性:
1.为了避免其它程序过多建立该类对象,先禁止其它程序建立该对象(将构造函数私有化)
2.还为了让其它程序可以访问到该类对象,只有在本类中,自定义一个对象
3.为了方便其它程序对自定义的对象访问,可以对外提供一个方法
具体实现方式:
1.将构造函数私有化2.在类中创建一个本类对象3.提供一个方法可以获取该对象,以便提供出去给外界使用
饿汉式:
public class Demo {
//将构造函数私有化,防止外界实例化对象
private Demo(){};
//在本类中定义一个Demo的实例
private static Demo demo=new Demo();
//外界如果想要得到Demo类在一个实例,只有通过下面这个方法,并且返回类型是Demo类型的
public static Demo getInstance()
{
return demo;
}
public static void main(String[] args)
{
Demo demo=Demo.getInstance();
//拿到Demo的一个实例以后,想对Demo做什么就做什么吧
}
}
懒汉式:对象是方法别调用是,才初始化,也叫做对象的延时加载。Demo1类进内存,对象还没有存在,只有调用了getInstance方法时才建立对象
public class Demo1 {
private Demo1(){};
private static Demo1 demo=null;
public static Demo1 getInstance()
{
if(demo==null)
{
synchronized(Demo1.class)
{
//双重判断为了消除安全隐患,没有将synchronized方法方法上是因为双重判断可以
//减少读锁的次数。
if(demo==null)
demo=new Demo1();
}
}
return demo;
}
public static void main(String[] args)
{
Demo1 demo=Demo1.getInstance();
}
}