1 静态导入
Jdk1.5新增加的静态导入可以在在程序中导入静态属性和方法,方便在程序中访问静态属性和静态方法
语法:import static 包名.类名.静态方法|静态属性
例子:
package it.example;
importstatic java.lang.System.out;//导入静态的方法;
importstatic java.lang.Math.sin;
importstatic java.lang.Math.*; //导入Math中所有的静态属性和静态方法
//import static java.lang.Math.PI; //导入静态的属性
publicclass testStaticImport {
publicstaticvoid main(String[] args) {
out.println("test");
System.out.println(sin(60));
System.out.println(abs(-35));
System.out.println(PI);
}
2 可变参数
Jdk1.5以后,java允许方法定义为长度可变的参数
语法:访问控制符返回值类型方法名( 可变参数类型…可变参数){ }
注意:可变参数将传进来的参数作为一个数组存取来,可以以数组的形式读取。
可变参数应为所有参数列表的最后定义,所以一个方法最多只有一个长度可变动的参数。
例子:
package it.example;
import java.util.Arrays;
import java.util.List;
public class testVaribleElement {
public void run(String i, int ...j){ //j:可变参数 j为数组;
System.out.println(i);
for(int k : j){
System.out.println(k);
}
}
public void test(){
List list = Arrays.asList("1","2","3");
System.out.println(list);
String[] str = {"1","2","3","4"};
list = Arrays.asList(str);
System.out.println(list);
Integer[] num = {1,3,4,5};
list = Arrays.asList(num);
System.out.println(list);
}
public static void main(String[] args) {
testVaribleElement t = new testVaribleElement();
t.run("hello",2,3,3,5);
t.test();
}
}
3 增强for循环
Jdk1.5之前,遍历数组的元素需要知道数组的长度,针对这种情况出现了增强的for循环
语法:for(数组或集合中的元素类型数组或集合中的元素: 数组或集合) {
}
注意此处的集合是实现了Iterate接口的集合
例子:
不使用增强for循环
Map map=new HashMap();
map.put("1", "aaa");
map.put("2", "bbb");
map.put("3", "ccc");
//传统方式1
Set set=map.keySet();
Iterator it=set.iterator();
while(it.hasNext()){
String key=(String)it.next();
String value=(String) map.get(key);
System.out.println("key="+key+",value="+value);
}
//传统方式2
Set set2=map.entrySet();
Iterator it2=set2.iterator();
while(it2.hasNext()){
Map.Entry entry=(Entry)it2.next();
System.out.println("key="+entry.getKey()+",value="+entry.getValue());
}
使用增强for循环
//增强for循环的1种方式
for(Object obj:map.keySet()){
String key2=(String)obj;
String value2=(String)map.get(key2);
System.out.println("key2="+key2+",value2="+value2);
}
//可以知道运用增强的for循环方便的多
//增强for循环的2种方式
for(Object obj:map.entrySet()){
Map.Entry entry3=(Entry) obj;
String key3=(String) entry3.getKey();
String value3=(String) entry3.getValue();
System.out.println("key3="+key3+",value3="+value3);
}
注意:一般来说,增强for循环只适合来取数据
4 自动装箱与拆箱
装箱是将基本数据类型封装成对应的对象类型,拆箱就是将对象类型拆成其对应的基本数据类型,把基本数据类型赋给其对应的对象类型,把对象类型赋给其对应的基本数据类型,会自动的进行装箱与拆箱。
package it.example;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class testAutoboxing {
public static void main(String[] args) {
Integer i = 1; //装箱,int 1 赋给其包装类型Integer;
int j = i; //拆箱;
List l = new ArrayList();
l.add(1);
l.add(2);
l.add(3);
// int k = (int)l.get(0);
int k = (Integer)l.get(0); //自动装箱拆箱
Iterator it = l.iterator();
while(it.hasNext()) {
int m = (Integer)it.next(); //拆箱
System.out.println(m);
}
}
}
5 枚举
为什么需要枚举类,一些方法在运行时,需要的的数据是几个指定数据中的一个,例如星期。Jkd1.5以前,解决这个问题是定义具有枚举性质特定的类似类。Jdk1.5提供了enum关键字来定义枚举类
例如:
package it.example;
publicclass TestEnum {
publicvoid test() {
print(Grade.B); //89-80,良
}
publicvoid print(Grade g)// A B C D E
{
String value=g.getValue();
String value2=g.localeValue();
System.out.println(value+","+value2);
}
publicstaticvoid main(String[] args) {
/* TestEnum t = new TestEnum();
// t.test();
t.print(Grade.A);
*/
Grade grade = Grade.A;
System.out.println(grade.name()); //A:得到枚举的名字
System.out.println(grade.ordinal()); //0:得到枚举的序号
System.out.println(grade.getValue());
System.out.println(grade.valueOf("B")); //B:得到enum B然后调用其toString方法打印。
System.out.println(grade.toString());
System.out.println(grade.values().clone()[2]);
for(Grade g : grade.values()){ //values方法遍历枚举中的值
System.out.println(g.name());
}
}
}
//带抽象方法的枚举
enum Grade {// class A 100-90优 B 89-80良 C 79-70 一般D 69-60差 E 59-0不及格
A("100-90"){
public String localeValue(){
return"优";
}
},//枚举值实现enum中定义的抽象方法localeValue()
B("89-80"){
public String localeValue(){
return"良";
}
},
C("79-70"){
public String localeValue(){
return"一般";
}
},
D("69-60"){
public String localeValue(){
return"差";
}
},
E("59-0"){
public String localeValue(){
return"不及格";
}
};// object元素列表必须定义在所有之前
private Stringvalue;
private Grade(String value){ //构造方法需定义为private
this.value=value;
}
public String getValue(){
returnthis.value;
}
publicabstract String localeValue();
}
枚举类有如下特性:
1是一种特殊的java类, enum 关键字声明是枚举类。可以在枚举类中定义属性,构造方法,成员方法,构造方法一般为private。枚举类可以实现接口,继承抽象类。
2 定义的枚举类中的枚举值必须定义所有元素定义之前 ,每一个枚举值均为publicstatic final 的。每一个枚举值代表的是枚举类的一个实例对象。
3 因为每一个枚举值是一个枚举类的实例对象,继承类enum的所有方法,很多方法是很实用的,比自己定义的模拟枚举的类方便的多。例如其values方法可以得到所有枚举类后遍历。
4 jdk5 中的switch支持以前的byte,char,short,int外,额外支持枚举类。
6 反射
什么是反射,反射就是把java类中的各种成分映射成一个一个的java对象。一个java类中有属性,构造方法,成员方法等等,描述java类这些共性的的类就是Class类。得到一个对象的java类的Class类有三种方法
1Class.forName(“类名”)
Class clazz = Class.forName("itcast.reflect.Person");
2类名.Class
Class clazz = Person.class;
3对象.getClass();
Person p = new Person();
Class clazz = p.getClass();
其中第一种加载资源的方法最常用。
要反射的Person类
package itcast.reflect;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class Person {
/**
* 各种属性的反射
* name:public
* password:private
* age: private static
*
*/
public String name = "Hwlo";
private String password = "password";
private static int age = 38;
/**
* 各种构造方法的反射
* 默认的构造方法
* 默认的构造方法的反射
* 带参数String name的构造方法的反射
* ...
*/
public Person() {
System.out.println("null");
}
public Person(String name) {
System.out.println(name);
}
public Person(String name,int age) {
System.out.println(name+","+age);
}
private Person(List list) {
System.out.println("list:"+list);
}
/**
* 各种成员方法的的反射
*/
public void run(){
System.out.println("null run");
}
public void run(String name){
System.out.println(name);
}
public void run(String[] name ,int age) {
System.out.println(name+","+age);
}
public static void run(int num) {
System.out.println(num);
}
private void run(InputStream in) {
System.out.println(in);
}
//main方法如何反射
public static void main(String[] args) {
System.out.println("main method");
System.out.println(args[0]);
}
}
反射Person类的构造函数
package itcast.reflect;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
//反射类构造方法
public class Demo2 {
@Test
public void test1() throws Exception {
Class clazz = Person.class;
Constructor c = (Constructor)clazz.getConstructor(null);
Person p = (Person) c.newInstance(null);//用了默认的构造函数new了一个对象
}
@Test
public void test2() throws Exception {
Class clazz = Class.forName("itcast.reflect.Person");
Constructor c = clazz.getConstructor(String.class); //拿到公有的构造函数
Person p = (Person) c.newInstance("hello");
}
@Test
public void test3() throws Exception {
Class clazz = new Person().getClass();
Constructor c = clazz.getConstructor(String.class,int.class);
Person p = (Person) c.newInstance("world",38);
}
@Test
public void test4() throws Exception {
Class clazz = Person.class;
Constructor c = clazz.getDeclaredConstructor(List.class); //getDeclaredConstructor方法拿到私有的构造函数
c.setAccessible(true); //获得访问权限
Person p = (Person) c.newInstance(new ArrayList());
}
//默认的调用构造函数
@Test
public void test5() throws Exception {
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
}
}
6.1 Constructor类:代表某类中的构造方法
>得到某个类(Person)所有的构造方法,clazz为得到的Person类的Class类。
Constructor[] constructor =clazz.getConstructors();
>得到某个类(Person)的某一个构造方法
Constructor constructor = clazz.getContructor(参数类型的Class) 默认的构造参数为null。
例如例子中的:
Constructor c = clazz.getConstructor(String.class);
Constructor c = (Constructor)clazz.getConstructor(null); //默认构造参数
Constructor c = clazz.getConstructor(String.class,int.class);
>创建某个类(Person )的对象
传统方式:Person person = new Person();
反射的方式:考虑访问修饰符,参数类型来实例化;
>对于访问控制符为private的构造方法
Constructor c =clazz.getDeclaredConstructor(List.class);
//getDeclaredConstructor方法拿到私有的构造函数
c.setAccessible(true); //获得访问权限
Personp = (Person) c.newInstance(new ArrayList());
>对于默认的构造方法
1.
Classclazz = Person.class;
Personp = (Person) clazz.newInstance();
2.
Constructorc = (Constructor)clazz.getConstructor(null);
Personp = (Person) c.newInstance(null);//用了默认的构造函数new了一个对象
>其他
Constructorc = clazz.getConstructor(String.class,int.class);
Personp = (Person) c.newInstance("world",38);
反射Person类的成员方法
package itcast.reflect;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import org.junit.Test;
//反射类中的方法
public class Demo3 {
@Test
public void test1() throws Exception {
Class clazz = Class.forName("itcast.reflect.Person");
Method method = clazz.getMethod("run", null);
Person p = new Person();
method.invoke(p,null);
}
@Test
public void test2() throws Exception {
Class clazz = Class.forName("itcast.reflect.Person");
Method method = clazz.getMethod("run", String.class);
Person p = new Person();
method.invoke(p,"hallo");
}
@Test
public void test3() throws Exception {
Class clazz = Class.forName("itcast.reflect.Person");
Method method = clazz.getMethod("run", String[].class,int.class);
Person p = new Person();
method.invoke(p,new String[]{"hello","world"},12);
}
@Test
public void test4() throws Exception {
Class clazz = Class.forName("itcast.reflect.Person");
Method method = clazz.getMethod("run", int.class);
// Person p = new Person();
// method.invoke(p,new String[]{"hello","world"},12);
method.invoke(null, 45); //静态方法不需要传递对象
}
@Test
public void test5() throws Exception {
Class clazz = Class.forName("itcast.reflect.Person");
// Method method = clazz.getMethod("run", InputStream.class);
Method method = clazz.getDeclaredMethod("run", InputStream.class);
method.setAccessible(true);
Person p = new Person();
method.invoke(p,new FileInputStream("reflect.txt")); //打印不出reflect.txt中的内容。
}
@Test
public void test6() throws Exception {
Class clazz = Class.forName("itcast.reflect.Person");
Method method = clazz.getMethod("main", String[].class); //获取main方法
method.invoke(null,(Object)new String[]{"hello","world"}); //注意此处的
}
}
6.2 Method类:代表某个类中的成员方法
>得到某个类(Person)的成员方法
>得到private的成员方法
Classclazz = Class.forName("itcast.reflect.Person");
// Methodmethod = clazz.getMethod("run", InputStream.class); //此方法不能获得private的方法,应调用getDeclaredMethod(”成员方法名”,参数.class,参数.class…);
Methodmethod = clazz.getDeclaredMethod("run", InputStream.class);
>得到main方法是
Classclazz = Class.forName("itcast.reflect.Person");
Methodmethod = clazz.getMethod("main", String[].class); //获取main方法
>其他
Classclazz = Class.forName("itcast.reflect.Person");
Methodmethod = clazz.getMethod("run", String.class); //getMethod方法
>调用某个类的成员方法
传统调用方式:person.方法名。
反射的方式:method.involve(对象,参数列表)
>调用private的成员方法
method.setAccessible(true); //获得访问权限
Personp = new Person();
method.invoke(p,newFileInputStream("reflect.txt"));
>调用静态的方法
method.invoke(null,45); //静态方法不需要传递对象,传递null值则表示调用的静态的方法,在调用main方法亦如此。
>调用main方法
method.invoke(null,(Object)newString[]{"hello","world"}); //注意此处的(Object),是为了兼容jdk1.4的
>调用其他
1.
Person p = newPerson();
method.invoke(p,null);//传递对象,无参数
2.
Person p = newPerson();
method.invoke(p,"hallo");//传递对象,参数
注意:调用main方法是,如果这样写method.invoke(null, newString[]{"hello","world"});则会出现参数类型不对的错误情况。这是因为jdk1.4与jdk1.5invoke方法的不同造成的
Jdk1.4 invoke方法:public Objectinvoke(Object obj,Object[] args);
Jdk1.5invoke方法:public Objectinvoke(Object obj,Object... args);按jdk1.4的语法,需要将一个数组作为参数传递给invoke方法时,数组中的每个元素分别对应被调用方法中的一个参数,会将传过来的参数new String[]{"hello","world"}中的元素打散给main方法传递参数,jdk1.5兼容jdk1.4,javac会按jdk1.4来理解,所以会出现参数类型不对的错误。解决方法如下:
mainMethod.invoke(null,new Object[]{newString[]{"xxx"}});
mainMethod.invoke(null,(Object)newString[]{"xxx"}); ,编译器会作特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干个参数了。
package itcast.reflect;
import java.lang.reflect.Field;
import org.junit.Test;
//反射类中的属性
public class demo4 {
@Test
public void test1() throws Exception {
Class clazz = Person.class;
Field f =clazz.getField("name");
Person p = new Person();
String value= (String) f.get(p);
Class type = f.getType();
System.out.println(type);
System.out.println(value);
//设置值
f.set(p, "change");
System.out.println(f.get(p));
}
@Test
public void test2() throws Exception {
Class clazz = Person.class;
// Field f =clazz.getField("password");
Field f = clazz.getDeclaredField("password");
f.setAccessible(true);
Person p = new Person();
String value= (String) f.get(p);
Class type = f.getType();
System.out.println(type);
System.out.println(value);
}
public void test3() throws Exception {
Class clazz = Class.forName("itcast.reflect.Person");
// Field f =clazz.getField("password");
Field f = clazz.getDeclaredField("age");
f.setAccessible(true);
// Person p = new Person();
// int value= (Integer)f.get(null); //获取static变量不需传入对象
// Class type = f.getType();
//
// System.out.println(type);
System.out.println(f.get(null));
}
}
6.3Field类:代表某个类(Person)中的属性
获得某个类(Person)的属性
>获得private的属性
Class clazz = Person.class;
//Field f =clazz.getField("password");//不能使用getField方法。
Field f =clazz.getDeclaredField("password");
>其他
Class clazz = Person.class;
Field f =clazz.getField("name");
给某个属性取值设置值
传统的方法:调用其getter,setter方法
反射的方法:
>给private的属性name取值设置值
f.setAccessible(true); //获得访问权限
Person p = new Person();
String value= (String) f.get(p);
f.set(p,”name”);
>给static的属性age取值设置值
Person p = new Person();
int value= (Integer)f.get(null); //获取static变量不需传入对象
f.set(null,365);
>其他属性password
Person p = new Person();
String value= (String) f.get(p);
f.set(p,”password”);