异常
异常的分类
- java的异常大致可分为运行时异常和普通异常。在使用IDE开发工具的时候运行时异常不会提示,这类异常一般在运行时才会出现,大致是有类转换异常,空指针异常,数组索引溢出异常等。通常这类异常都是设计代码时候一些错误导致的。
- 普通异常就是可以在编写代码时就能捕获的异常,这种异常只要在程序正常运转的情况下一般不会出现,就例如服务器掉线等硬件问题导致的异常。所谓的异常的捕获就是指通过编写代码时把可能会出现异常的代码做try…catch处理。
- e.g 一个简单的字节流文件复制代码
public class TestException {
public static void main(String[] args) {
FileInputStream in=null;
FileOutputStream out=null;
File file=new File("xxx.txt");
System.out.println(file.exists());
try {
in=new FileInputStream(file);
out=new FileOutputStream("xxx_copy.txt");
int i;
byte[] b=new byte[1024];
while((i=in.read(b))!=-1) {
out.write(b);
out.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(in!=null) {
in.close();
}
if(out!=null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
- 捕获的异常可以立刻处理也可以选择抛出(throw),抛出异常是由语句来完成的,但是当语句抛出后必须在相应的方法或者类中加入throws语句异常的抛出机制是逐级上抛,最后到类时若还未处理异常,就需要在类的声明语句中加入一条throws xxException。
- 异常类可以自己定义,自定义的异常类需要继承Exception类。Throwable接口是异常类的顶级接口,Exception是一个实现类,还有一个类是Error。
反射
反射的概述
- java中的反射机制就是可以在运行时通过类名或者对象变量来获取对应的类信息,进一步可取得类中定义的成员。总的来说反射是一种解析类的机制。
- 个人的理解:java中Class类中封装了类运行时的信息:变量,方法,构造器等,Class 类的对象是在加载类时由 Java 虚拟机自动创建的,通过Class类对象可以取得上述成员对应的封装类(Field,Method,Constructor)。常用的方法如下:
获取Class:对象.getClass()或者Class.forName(“包名.类名”)或类名.class
i.getName():返回String形式的该类的名称。
ii.getConstructors() :返回当前 Class 对象表示的类中所有可见的构造器组成的Constructor数组。
iii.getDeclaredConstructors() :返回当前 Class 对象表示的类中声明的构造器组成的Constructor数组。
iv.getDeclaredFields():返回当前 Class 对象表示的类中声明的Field数组。
v.getFields() :返回当前 Class 对象表示的类中可访问的Field数组。
vi.getDeclaredMethods() :返回 Class 对象表示的类中声明的方法Method数组。
vii.newInstance() :创建类的新实例。
public class TestReflect {
private int age;
private String name;
private byte[] b;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public byte[] getB() {
return b;
}
public void setB(byte[] b) {
this.b = b;
}
public TestReflect(int age, String name, byte[] b) {
super();
this.age = age;
this.name = name;
this.b = b;
}
public TestReflect() {
super();
}
@Override
public String toString() {
return "TestReflect [age=" + age + ", name=" + name + ", b=" + Arrays.toString(b) + "]";
}
private void info() {
System.out.println("age:"+this.age+",age:"+this.name);
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
TestReflect instanceA=new TestReflect();
byte[] b=new byte[] {1,2,3,4,5,6,7,8,9,10};
TestReflect instanceB=new TestReflect(18, "尾巴", b);
System.out.println(Class.forName("com.leeyu.test.TestReflect").getName());
System.out.println(instanceA.getClass().getName());
System.out.println(TestReflect.class.getName());
TestReflect instanceC=TestReflect.class.newInstance();
Constructor constructor=TestReflect.class.getDeclaredConstructor(
int.class,String.class,byte[].class);
TestReflect instanceD=(TestReflect) constructor.newInstance(18,"尾巴",b);
System.out.println(instanceA);
System.out.println(instanceB);
System.out.println(instanceC);
System.out.println(instanceD);
Method info=TestReflect.class.getDeclaredMethod("info");
info.setAccessible(true);
System.out.println(info.isAccessible());
TestReflect instanceE=TestReflect.class.newInstance();
Field parameters=TestReflect.class.getDeclaredField("age");
parameters.set(instanceE, 20);
System.out.println(instanceE);
}
}
------------------------------------------------------------------------
输出结果:
com.leeyu.test.TestReflect
com.leeyu.test.TestReflect
com.leeyu.test.TestReflect
TestReflect [age=0, name=null, b=null]
TestReflect [age=18, name=尾巴, b=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
TestReflect [age=0, name=null, b=null]
TestReflect [age=18, name=尾巴, b=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
true
TestReflect [age=20, name=null, b=null]
泛型
- 在我理解中的泛型是一种规定数据类型的方式,适用于集合,方法,变量,类等。举一个简单的例子:
List<String> list=new ArrayList<String>;
这行代码规定了list这个集合中存入的数据必须都是String类型的,可以看出泛型是通用<泛型>来应用的,用户可以自己规定泛型。 - i.泛型在集合中的应用:
public static void main(String[] args) {
List<String> list=new ArrayList();
list.add("abc1");
list.add(1, "abc2");
list.add(2, "abc3");
for(String e:list) {
System.out.println(e);
}
}
}
- ii.泛型在方法和变量中的应用(需要自定义泛型类)
package com.leeyu.test;
import java.util.List;
import java.util.ArrayList;
public class TestDataType<T> {
private T info;
public T getInfo() {
return info;
}
public void setInfo(T info) {
this.info = info;
}
public static void main(String[] args) {
TestDataType<Addr> testAddr=new TestDataType<Addr>();
testAddr.setInfo(new Addr("中国","河北","石家庄"));
System.out.println(testAddr.getInfo());
}
}
class Addr{
private String country;
private String city;
private String town;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getTown() {
return town;
}
public void setTown(String town) {
this.town = town;
}
public Addr(String country, String city, String town) {
super();
this.country = country;
this.city = city;
this.town = town;
}
public Addr() {
super();
}
@Override
public String toString() {
return "Addr [country=" + country + ", city=" + city + ", town=" + town + "]";
}
}
---------------------------
结果:Addr [country=中国, city=河北, town=石家庄]