关于Java基础的文章,我觉得写得还可以,以前发在了我其它的博客了,肯定是原创,现在再分享给大家出来。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
JavaBean是符合某种规范的Java组件,也就是Java类。
它必须满足如下规范:
1)必须有一个零参数的默认构造函数
2)必须有get和set方法,类的字段必须通过get和set 方法来访问。
(get方法无参,set方法有参)
比如下面的一个类就是一个JavaBean类
package cn.jinfulin.day2.javabean;
/**
* @author 金福林
*
*/
public class UserBean {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
那么javabean类如何操作呢,这里就要说一下java内省机制了。
JDK提供了对JavaBean进行一些操作的API,这套API就是内省。
内省(Introspector)是Java语言对Bean类属性、事件的一种缺省处理方法。
例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新的值。
通过内省调用JavaBean示例
package cn.jinfulin.day2.javabean;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author 金福林
*
*/
public class IntroBean {
public static void main (String[] args) throws Exception{
String propertyName = "name";
Object user = new UserBean();
setMethod(propertyName, user);
getMethod(propertyName, user);
}
private static void getMethod(String propertyName, Object user)
throws IntrospectionException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
PropertyDescriptor pd = new PropertyDescriptor(propertyName, user.getClass());
Method MethodGetName = pd.getReadMethod();
MethodGetName.invoke(user, null);
}
private static void setMethod(String propertyName, Object obj) throws Exception{
//PropertyDescriptor 描述 Java Bean 通过一对存储器方法导出的一个属性。
PropertyDescriptor pd = new PropertyDescriptor(propertyName,obj.getClass());
Method MethodSetName = pd.getWriteMethod();
MethodSetName.invoke(obj, "jinfulin");
}
}如下,改写的setMethod方法
private static Object setMethod(String propertyName, Object obj) throws Exception{
BeanInfo bean = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] pds = bean.getPropertyDescriptors();
Object returnvalue = null;
for (PropertyDescriptor pd : pds) {
if (pd.getName()==propertyName) {
Method methodGetX = pd.getReadMethod();
returnvalue = methodGetX.invoke(obj);
}
}
return returnvalue;
}BeanUntils工具包是针对javabean的操作属性的工具类,使用比较广泛。
它并不是sun公司开发的而是阿帕奇公司开发的第三方工具包,需要单独下载才能使用。
导入jar包的方法比较简单,就不详细说了,但是要记的不仅要导入BeanUntils工具包,还要导入logging包
public static void main(String[] args) throws Exception{
UserBean bean = new UserBean();
BeanUtils.setProperty(bean, "name", 12);//set方法
BeanUtils.getProperty(bean, "name");//get方法
}此时再调用Javabean的set和get方法,一下子就变得只剩下2行代码了,感觉棒棒哒。
假如我的javaBean类返回的是对象,而这个对象还拥有get和set方法(比如date对象有getTime()和setTime()方法)
比如
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}BeanUtils.setProperty(bean, "birthday.time", 12);
PropertyUtils工具类用法跟BeanUtils基本一样。
区别:
1)BeanUtils会对JavaBean的属性的类型进行转换,如属性本身是integer,会转换为String。
2)PropertyUtils以属性本身的类型进行操作。
注解可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。
在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记。
1,Override----表示一个方法声明打算重写超类中的另一个方法声明。
2,Deprecated----过时的
3,SuppressWarnings----忽略警告信息(不提示过时信息)
public static void main(String[] args) {
//如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。
if (AnnotationTest.class.isAnnotationPresent(IAnncation.class)) {
//如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
IAnncation anno = AnnotationTest.class.getAnnotation(IAnncation.class);
System.out.println(anno);
}
}上面那个反射的例子直接执行是肯定不能成功的,因为我们还没有写注解类,也没有更改元注解的内容。
元注解就是在定义注解类的时候加注解,元注解通常包括两个,即Retention和Target。
Retention有三种取值
RetentionPolicy.SOURCE----java源文件时期,编译器要丢弃的注释。
RetentionPolicy.CLASS--- 编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。(默认)
RetentionPolicy.RUNTIME----编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。
//运行时检测注释
@Retention(RetentionPolicy.RUNTIME)
public @interface IAnncation {
}用于注解类的使用位置
ElementType.TYPE------ 类、接口(包括注释类型)或枚举声明可以使用该注解
ElementType.METHOD-----方法中可以使用该注解
ElementType.ANNOTATION_TYPE ------注释类型声明
CONSTRUCTOR ------构造方法声明
FIELD -------字段声明(包括枚举常量)
LOCAL_VARIABLE------局部变量声明
PACKAGE ------- 包声明
PARAMETER --------参数声明
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.ANNOTATION_TYPE})
public @interface IAnncation {
}如果只有一个value名称的属性或其他属性缺省,则可@注解名(”属性值”);
如果有多个或不缺省或者需重新赋值,则@注解名(属性名=”属性值”,…)。
//运行时检测注释
@Retention(RetentionPolicy.RUNTIME)
//注释可以放在的位置,这里表示在方法可类中均可
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.ANNOTATION_TYPE})
public @interface IAnncation {
//为注解添加方法,默认值是green
String color() default "green";
//当有且只有value属性时候,=号可以省略
String value() default "默认";
//一个数组方法,如果只有一值,大括号可以省略
int[] arr() default {1,2};
//调用时比如
//@IAnncation(color = "red",arr = {2,2,3})
}@IAnncation(color = "red", arr = { 2, 2, 3 })类加载器说简单一点就是加载类的工具。
一般来说,Java 虚拟机使用 Java 类的方式如下:
Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。
类加载器负责读取 Java 字节代码,并转换成 java.lang.Class类的一个实例。每个这样的实例用来表示一个 Java 类。
通过此实例的 newInstance()方法就可以创建出该类的一个对象。
将.class文件中的内容变为字节码加载进内存。
Java 中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由 Java 应用开发人员编写的。
系统提供的类加载器主要有下面三个:
引导类加载器(BootStrap):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader。
扩展类加载器(ExtClassLoader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
统类加载器(AppClassLoader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。
可以通过 ClassLoader.getSystemClassLoader()来获取它。
public class ClassLoaderTest {
public static void main(String[] args) {
System.out.println(System.class.getClassLoader());//null
System.out.println(ClassLoaderTest.class.getClassLoader().getClass()
.getName());//AppClassLoader
}
}
每个类加载器只能加载特定位置的类,对于不在它指定位置的类,可以委托给其他的类加载器去加载。
具体是:
比如一个默认的java应用类应该由AppClassLoader加载,
首先并不加载,而是委托给它的爸爸:ExtClassLoader,但是Ext也不加载,因为它还有爸爸,再次委托给BootStap
BootStap没有爸爸了,就找自己指定的目录--rt.jar包下没有,再让它的儿子ExtClassLoader去找,ext目录下也没有,再让它孙子AppClassLoader去找。
找到了,就加载,找不到就报异常,不会再往下找了(因为从这里开始的)
①,继承抽象类ClassLoader
②,覆写其中的findClass(String name)方法
③,返回defineClass()方法。比如:return defineClass(null, buf, 0, buf.length);
a,要加密的类
package cn.jinfulin.day2.ClassLoader;
import java.util.Date;
public class Sercert extends Date {
@Override
public String toString() {
return "我是加密文件";
}
}
/*
* 简单加密算法
*/
private static void cypher(InputStream in,OutputStream out)throws Exception {
int b = -1;
while((b = in.read())!= -1){
out.write(b ^ 0xff);
}
} public static void main(String[] args) {
String srcPath = "C:\\Users\\金福林\\workspace\\staticimport\\bin\\cn\\jinfulin\\day2\\ClassLoader\\Sercert.class";
String DestFileName = srcPath.substring(srcPath.lastIndexOf("\\") + 1);
String destPath= "F:\\test\\" + DestFileName;
FileInputStream in = new FileInputStream(srcPath);
FileOutputStream out = new FileOutputStream(destPath);
cypher(in,out);
// System.out.println(new Sercert().toString());
Class clazz = new ClassLoaderTest().loadClass("Sercert.class");
Object obj = clazz.newInstance();
System.out.println(obj);
}
e,自定义类加载器,用于解密文件(继承ClassLoader,覆写findClass()方法)
public class ClassLoaderTest extends ClassLoader{
public static void main(String[] args) throws Exception {
Class clazz = new ClassLoaderTest().loadClass("Sercert.class");
Object obj = clazz.newInstance();
System.out.println(obj);
}
/*
* 自定义类加载器,用于解密类
* @see java.lang.ClassLoader#findClass(java.lang.String)
*/
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
String classFileName = "f:\\test\\" + name;
InputStream ips=null;
try {
ips=new FileInputStream(classFileName);
ByteArrayOutputStream bos=new ByteArrayOutputStream();//定义字节数组流
cypher(ips,bos);//解密
ips.close();
byte[] buf=bos.toByteArray();//取出字节数组流中的数据
return defineClass(null, buf,0,buf.length);//加载进内存
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
到这里JDK1.5的新特性总算写完了,最后再来回顾一下jdk1,5d新特性有:泛型、枚举、增强型for循环、反射、注解类、javabean、类加载器、静态导入、可变参数、自动拆装箱。
原文:http://blog.csdn.net/jinfulin/article/details/44967593