java高新技术上《九》
一:java1.5新特性(1:提高安全性 2:提高效率 3:简化书写)
1.静态导入
import :导入某个类或,某个包下的所有类。
import static : 导入某个类中的所有静态成员或某个静态成员
a.导入某个类的所有静态成员(方法和变量): import static 包名.类名.*;
b.导入某个类的某个静态成员: import static 包名.类名.静态成员名称;
2.可变参数(方法的参数)
为了增强方法的重载,使得方法可以接收多个(不确定)参数,Java通过隐式的创建一个数组来存储
可变参数,在方法内可以以数组形式访问它。
注意:可变的参数只能在参数列表的后面。
用法:add(3); //只传入x=3, add(3,4,5,6); //x=3,后面的赋给数组args.
public static void add(int x,int ...args)
{
int sum=x;
for(int e:args)
{
sum+=e;
}
System.out.println("add:"+sum);
}
3.自动拆装箱操作
装箱:将基本数据类型包装为对应的包装类对象
拆箱:将包装类对象转换成对应的基本数据类型
//JDK5.0之前:
Integer obj1 = Integer.valueOf(1);
//JDK5.0之后:
Integer obj2 = 2; //自动装箱:将基本数据类型转换成Integer对象
Integer it=4;
int i=it+5;
Integer it2=i+4;
System.out.println(obj2 + 3); //自动拆箱:将Integer对象转换成基本数据类型后相加
//-128~127的数字包装成Integer对象后,会缓存到一个对象池中,当要用到的时候会先到池中找
//提高效率:因为这些小整数会经常用到
Integer obj3 = 127;
Integer obj4 = 127;
System.out.println(obj3 == obj4);
Integer obj5 = 128;
Integer obj6 = 128;
System.out.println(obj5 == obj6);
Integer obj7 = Integer.valueOf(1);
System.out.println(obj1 == obj7);
运行结果:5
true
false
true
4.增强性for循环
好处:适合用于遍历,提高了效率。
坏处:无法得知变量的下标。
注意: 只能是数组或集合类型(实现了Iterator接口)
用法: for( type 变量名:变量集合名) ,如上
二:枚举
定义:枚举也是一种类,只是比较特别,它将所有的有限个实例对象放在它的内部,你可以通过“枚举名.枚举实例”来访问它的实例对象。
适用环境:当你用到某个类,而且它只有有限个实例对象,它的类型不确定很抽象的时候,你可以考虑将它定义成枚举类,如红绿灯,季节等。
枚举类的常用方法:
(1) ordinal()方法: 返回枚举值在枚举类种的顺序。这个顺序根据枚举值声明的顺序而定。
(2) compareTo()方法: Enum实现了java.lang.Comparable接口,因此可以比较与指定对象的顺序。Enum中的compareTo返回的是两个枚举值的顺序之差。当然,前提是两个枚举值必须属于同一个枚举类,否则会抛出ClassCastException()异常。
(3) values()方法: 静态方法,返回一个包含全部枚举值的数组。
(4) toString()方法: 返回枚举常量的名称。
(5) valueOf(Class<T> enumType, String name)方法: 这个方法和toString方法是相对应的,返回带指定名称的指定枚举类型的枚举常量。
(6) equals()方法: 比较两个枚举类对象的引用。
1.枚举类
一个类的实例是有限且固定的,则这个类称为枚举类。比如季节类,只有四个对象(春、夏、秋、冬)。
1 //创建一个枚举类的
2 /*
3 (1)通过private将构造器隐藏起来
4 (2)把这个类的所有可能实例都使用private static final修饰的类变量来保存。
5 (3)如果有必要,可以提供一些静态方法。
6 */
7 public class Demo
8 {
9 public static void main (String []args)
10 {
11 System.out.println("spring:"+Season.SPRING.getName());
12 }
13 }
14 class Season
15 {
16 private String name;
17 private Season (String name)
18 {
19 this.name=name;
20 }
21 public static final Season SPRING=new Season ("春天") ;
22 public static final Season SUMMER=new Season("夏天");
23 public static final Season AUTUMN=new Season ("秋天");
24 public static final Season WINTER=new Season ("冬天");
25 public String getName()
26 {
27 return this.name;
28 }
29
30 }
2.不可变类
不可变类:创建该类的实例后,该实例的Field是不可改变的。
如果要创建自定义的不可变类,需遵循如下规则:
- 使用private和final修饰符来修饰该类的Field。
- 提供带参数的构造函数,用于根据传入参数来初始化类里的Field。
- 仅为该类的Field提供getter方法,不要为该类的Field提供setter方法。
- 如果有必要,重写Object类的hashCode和equals方法。
3.Enum类(枚举)
- 使用enum关键字定义枚举类。枚举类一样可以有自己的Field、方法,可以实现一个或多个接口,也可以有自己的构造器。
- 使用eunm定义的枚举类默认继承了java.lang.Enum类,而不是继承Object类。
- 使用enum定义、非抽象的枚举类默认会使用final修饰,因此枚举类不能派送子类。(并不是所有的枚举类都使用final修饰,如抽象枚举类)
- 枚举类所有实例必须在枚举类的第一行显示列出,否则这个枚举类永远不能产生实例。
- 所有枚举类都提供一个values方法,该方法可以方便地遍历所有枚举值。
enum的常用静态方法:
枚举类名.values() ;//以数组的形式返回该枚举的所有实例
Enum.valueOf(枚举类名.class,枚举实例名); //返回该枚举类下指定的枚举实例。
1 //访问枚举类的实例,或方法,以“枚举类名.实例”,“枚举类名.方法名”访问
2 //使用enum定义一个简单的枚举类
3 //使用enum的values()方法,遍历所有的枚举
4 public class Demo1
5 {
6 public static void main(String []args) throws Exception
7 {
8 method(SeasonEnum.SUMMER);
9 method2();
10 }
11 public static void method2()
12 {
13 for ( SeasonEnum se: SeasonEnum.values() )
14 {
15 System.out.println("SeasonEnum:"+se);
16 }
17 }
18 public static void method(SeasonEnum s)
19 {
20 switch (s)
21 {
22 default: System.out.println("null"); break;
23 case SPRING: System.out.println("spring"); break;
24 case SUMMER: System.out.println("summer"); break;
25 case AUTUMN: System.out.println("autumn"); break;
26 case WINTER: System.out.println("winter"); break;
27
28 }
29
30 }
31 }
32 enum SeasonEnum
33 {
34 SPRING ,SUMMER, AUTUMN ,WINTER ;
35
36 }
3.1一个规范化的枚举类(拥有自己不可变的Field)
1 /*
2 枚举类可以定义自己的Field和方法。
3 枚举类通常应该设计不可变类。其Field值不应该允许改变,这样会更安全。
4 所以枚举类的Field都应该使用private final修饰。
5 枚举实例名称一般都是大写字母
6 Enum.valueOf()方法演示
7 */
8 enum Gender
9 {
10 MALE("男"),FEMALE("女");
11 private Gender(String sex)
12 {
13 this.sex=sex;
14 }
15 private final String sex;
16 public String getSex()
17 {
18 return sex;
19 }
20 }
21 public class Demo2
22 {
23 public static void main (String []args)
24 {
25 Gender g=Gender.MALE;
26 System.out.println("Gender.MALE:"+g.getSex());
27 //使用Enum.valueOf()方法访问枚举类下的某个实例
28 Gender g2=Enum.valueOf(Gender.class,"FEMALE");
29 System.out.println("Enum.valueOf(Gender.class,\"FEMALE\"):"+g2.getSex());
30 }
31 }
3.2枚举类实现一个或多个接口(且不同枚举实例有各自的接口实现方法)
1 //枚举类实现一个或多个接口(且不同枚举实例有各自的接口实现方法)
2 public class Demo3
3 {
4 public static void main (String []args)
5 {
6 Gender.MALE.info();
7 }
8 }
//以下代码需要放在GenderInter.java文件中
public interface GenderInter
{
public void info();
}
enum Gender implements GenderInter
{
MALE("男")
{
public void info()
{
System.out.println("我是男的");
}
},FEMALE("女")
{
public void info()
{
System.out.println("我是女的");
}
};
private Gender(String sex)
{
this.sex=sex;
}
private final String sex;
public String getSex()
{
return sex;
}
}
3.3 包含抽象方法的枚举类
含有抽象方法的枚举类,它的每一个枚举实例必须覆盖重写该抽象方法
1 //注意:含有抽象方法的枚举类,它的每一个枚举实例必须覆盖重写该抽象方法
2 public class EnumAbstractDemo {
3
4 /**
5 * @param args
6 */
7 public static void main(String[] args) {
8 // TODO Auto-generated method stub
9 System.out.println("plus:5+2="+Operation.PLUS.eval(5, 2));
10 System.out.println("minus:5-2="+Operation.MINUS.eval(5, 2));
11 System.out.println("times:5*2="+Operation.TIMES.eval(5, 2));
12 System.out.println("divide:5/2="+Operation.DIVIDE.eval(5, 2));
13 }
14
15 }
16 enum Operation
17 {
18 //定义四种加减乘除的枚举值
19 PLUS {
20 @Override
21 public double eval(double x, double y) {
22 // TODO Auto-generated method stub
23 return x+y;
24 }
25 },MINUS {
26 @Override
27 public double eval(double x, double y) {
28 // TODO Auto-generated method stub
29 return x-y;
30 }
31 },TIMES {
32 @Override
33 public double eval(double x, double y) {
34 // TODO Auto-generated method stub
35 return x*y;
36 }
37 },DIVIDE() {
38 @Override
39 public double eval(double x, double y) {
40 // TODO Auto-generated method stub
41 return x/y;
42 }
43 };
44 public abstract double eval(double x,double y);
45 }
三:反射
1.反射
反射库(Reflection Library)提供一个丰富的工具集,以便编写能够动态操作Java代码的程序。这项功能被
大量的应用在JavaBeans中,它是Java组件的体系结构。
能够分析类能力的程序称为反射(Reflection),即可以将一个类(或基本数据类型),类成员当成一个对象来操作。
它是运行时检测和修改某个对象的结构及其行为,与内省(introspection)不同。内省是反射的一个子集。
反射:用于运行时检测和修改某个对象的结构及其行为。
内省:用于运行时检测某个对象的类型及其包含的属性。
注意:这里是指运行时期,即如果编译时期不可以做的事情,我在运行时期使用反射就可以做了,如向定义了ArrayList <String>的集合里,运用反射加入int型数据
内省实例: 对象名 instanceof 类名/接口名;//检测某个对象是否属于某个类或接口
反射实例:Class.forName()方法可以获取某个类。
2.Class类
一个Class对象实际上表示的是一个类型,这个类型不一定是一种类,因为它也可以表示基本数据类型。
它可以将Java里的所有东西(类,接口,数组,基本数据类型,void)当成一个对象来对它的属性进行访问。
3.反射包(java.lang.reflect)下的Constructor类,Field类(成员变量),Method类(成员方法)
总结:
1,创建Class实例对象的三种方法:
a,Class<?> c=Class.forName(String name);
b,Class<?> c=p.getClass();//对象名.getClass()
c,Class<?> c=Person.Class ;//类名.Class;
2,获取构造方法(Constructor),成员变量(Field),成员方法(Method),接口(interface)
Class类: getDeclaredXxxx();// 获取本类中的所有Xxxx,不包括继承父类中xxx
getXxxx();//获取本类中的public权限的Xxxx。
package hq.com.ClassDemo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ClassDemo {
/**
* class类的演示
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Demo1();
System.out.println("---------------------");
Demo2();
System.out.println("---------------------");
Demo3();
System.out.println("---------------------");
Demo4();
System.out.println("---------------------");
Demo5();
System.out.println("---------------------");
Demo6();
System.out.println("---------------------");
Demo7();
System.out.println("---------------------");
Demo8();
}
//1.任何所有东西都是Class类的实例对象
//创建Class实例的三种方法,Class.forName(),类名.class,对象名.getClass().
public static void Demo1() throws ClassNotFoundException
{
Class<?> c1=null;
Class<?> c2=null;
Class<?> c3=null;
//1,Class.forName()方法,推荐
c1=Class.forName("hq.com.ClassDemo.Person");
System.out.println("Demo1(写法1:forName()):类名="+c1.getName());
//2,类名.class。在java中,每个class都有一个相应的Class对象,当编写好一个类,
// 编译完成后,在生成的.class文件中,就产生一个class对象
c2=Person.class;
System.out.println("Demo1(写法2:类名.class):类名="+c2.getName());
//3,object类的getClass()方法
Person p=new Person();
c3=p.getClass();
System.out.println("Demo2(写法3:getClass()):类名="+c3.getName());
}
// 2,Object的getClass()方法,Class的getName(),getPackage().
// 演示反射机制获取类的包名和类名
public static void Demo2() {
Person p = new Person("hq", 22);
System.out.println("person的类名:" + p.getClass().getName());
System.out.println("person的包名:" + p.getClass().getPackage().getName());
}
//3,class的newInstance()方法
// 通过反射,用class来创建类对象(这是反射的意义所在)
public static void Demo3() throws Exception
{
Class c=Class.forName("hq.com.ClassDemo.Person");
Person p= (Person) c.newInstance();//要强转,默认是Object类
p.setName("hq");
System.out.println("Demo3(class的newInstance()方法):name="+p.getName());
}
//4,class的getConstructors();以数组形式返回该类的所有公共构造方法
// java.lang.reflect.Constructor;构造方法类
public static void Demo4() throws Exception
{
//用构造方法类创建该类的实例对象。
//注意必须按顺序获取Constructor,即ct[0]在ct[1]之前,不能反过来
Class c = null;
Person p1 = null;
Person p2 = null;
c = Class.forName("hq.com.ClassDemo.Person");
Constructor<?> [] ct=c.getConstructors();
p1=(Person) ct[0].newInstance();
p1.setName("hh");
p2=(Person) ct[1].newInstance("hq",22);
System.out.println("Demo4(getConstructors()构造方法类创建实例对象):p1:name="+p1.getName());
System.out.println("Demo4(getConstructors()构造方法类创建实例对象):p2:name="+p2.getName());
}
//5,class: getDeclaredField(String name);获取该类的成员变量
// Field类:操作类对象的成员变量,set,get方法
public static void Demo5() throws Exception
{
//class的getDeclaredField(String name)方法获取类中的某个成员变量
//Field类的set(Object obj,Object value),修改该字段上某个对象对应的值
Class c=Class.forName("hq.com.ClassDemo.Person");
Person p=(Person)c.newInstance();
Field f=c.getDeclaredField("age");
f.setAccessible(true);
f.set(p, 11);
System.out.println("Demo5(Field的set(对象,值)):person:age="+p.getAge());
System.out.println("Field.get():"+f.get(p));
}
//6,获取该类的父类信息,成员方法,接口,成员变量(字段)
public static void Demo6() throws Exception
{
//注意:getDeclaredFields()和getFields()区别是,
//前者是所有声明的字段,后者是仅为public权限的字段
//注意:两者获取的字段均为该类内部中定义的,不包括继承父类的字段
Class<?> c=Class.forName("hq.com.ClassDemo.SuperMan");
Class<?> superClass=c.getSuperclass();
System.out.println("Demo6:superman的父类是:"+superClass.getName());
//获取类中所有字段
Field [] fs=c.getDeclaredFields();
int i=0;
for(Field f:fs)
{
i++;
System.out.println("superman的第"+i+"个成员:"+f.getName());
}
//获取类中所有方法
Method [] ms=c.getDeclaredMethods();
for(Method m:ms)
{
i++;
System.out.println("superman的第"+i+"个成员方法:"+m.getName());
}
//获取类实现的接口
Class<?>[] is=c.getInterfaces();
for(Class<?> j:is)
{
System.out.println("superman的第"+i+"个接口:"+j.getName());
}
}
//7,调用类的方法,Method类的invoke()方法
public static void Demo7() throws Exception
{
Class<?> c=Class.forName("hq.com.ClassDemo.SuperMan");
//调用类中的无参数方法
Method m1=c.getMethod("fly");
System.out.print("Demo7:superman中的无参数方法fly():");
m1.invoke(c.newInstance());
//调用类中的参数方法,先取出该方法,再放入参数(实例,方法参数)
Method m2=c.getMethod("walk",int.class);
System.out.print("Demo7:superman中的有参数方法walk():");
m2.invoke(c.newInstance(),4);
}
/**
* Demo8: 通过Java反射机制得到类加载器信息
*
* 在java中有三种类类加载器。[这段资料网上截取]
1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。
2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类
3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。
*/
public static void Demo8() throws ClassNotFoundException
{
Class<?> class1 = null;
class1 = Class.forName("hq.com.ClassDemo.SuperMan");
String nameString = class1.getClassLoader().getClass().getName();
System.out.println("Demo8: 类加载器类名: " + nameString);
}
}
class SuperMan extends Person implements ActionInterface
{
private boolean BlueBriefs;
public boolean isBuleBriefs()
{
return this.BlueBriefs;
}
public void setBuleBriefs(boolean BlueBriefs)
{
this.BlueBriefs=BlueBriefs;
}
public void fly()
{
System.out.println("超人会飞哦~~");
}
@Override
public void walk(int m) {
// TODO Auto-generated method stub
System.out.println("超人也会走耶~~走了"+m+"米后走不动了");
}
}
interface ActionInterface
{
public void walk(int m);
}
class Person {
private int age;
private String name;
public Person() {
}
public Person(String name, int age) {
this.age = age;
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
总结:
数组的反射:
1.具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。
2.代表数组的Class实例对象的getSuperclass()方法返回的父类为Object类对应的Class.
3.基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用;非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用。
4.Arrays.asList()方法处理int[]和String[]时的差异。
Arrays工具类用于完成对数组的反射操作。