本文主要包含加密(MD5、SHA加密)、创建对象的4种方式、反射、PropertyDescriptor来操作JavaBean、使用BeanUtils操作JavaBean、自定义泛型、注解
1.加密(MD5、SHA加密)
package cn.lsl;
import java.security.MessageDigest;
import sun.misc.BASE64Encoder;
public class UseEnum {
public static void main(String[] args) throws Exception{
//MD5,SHA加密
String str = "1234";
MessageDigest m = MessageDigest.getInstance("MD5");
byte[] b = m.digest(str.getBytes());
//测试MD5加密后输出的
String an = new String(b);
System.out.println(">>>:"+an); //输出用MD5加密的
//输出的是乱码,需要进行编码
BASE64Encoder b64 = new BASE64Encoder();
String ss = b64.encode(b);
System.out.println(">>>:"+ss);
}
}
提醒:若出现出错:Access restriction: The type BASE64Encoder is not accessible due to restriction on required library
//去掉原先的JRE System Library,重新加载JRE System Library
2.创建对象的4种方式
1)使用new关键字实例化。
2)调用对像的clone(克隆 )方法。
package cn.lsl.clone;
public class Cat implements Cloneable{ //一个对象要能实现clone,必须实现此接口
private String name;
private String skin;
public Cat(String name, String skin){
this.name = name;
this.skin = skin;
System.out.println("init....");
}
public String toString(){
return name+",------"+skin;
}
@Override
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
测试类:
Main .java
package cn.lsl.clone;
public class Main {
public static void main(String[] args) throws CloneNotSupportedException{
Cat c1 = new Cat("Tom", "Yellow");//要想调用clone必须要先拥有一个这样的对象
Cat c2 = (Cat) c1.clone(); //调用clone方法,在clone时,不会再调用对象的构造方法,但是会分配新的地址
System.out.println(c1==c2);
System.out.println(c2+","+c1);
}
}
3)运用序列化和反序列化手段。
4)通过Class.forName(“…”).newInstance()或java.lang.reflect.Constructor反射手段。
反射:一种类的加载方式。通过一个字符串(如: “cn.itcast.Person”),就可以实例化一个类。
eg:
package cn.lsl.reflect;
import java.lang.reflect.Method;
import org.junit.Test;
public class ReflectTest {
public ReflectTest(){
System.out.println("init......");
}
public void abc(){
System.out.println("aassddd");
}
public static void main(String[] args) throws ClassNotFoundException, Exception, Exception {
Class cls = Class.forName("cn.lsl.reflect.ReflectTest"); //加载字节码
Object o = cls.newInstance(); //初始化
//调用方法
Method m = cls.getMethod("abc");
m.invoke(o);
//invoke(Object obj, Object...args)
//Object obj:调用谁的方法,给这个方法传什么参数
}
}
通过Class.forName加载了类的字节码文文件,并赋给一个Class类型的对像。在字节码文件中保存了类的所有信息,当然包括私有成员信息。
3.可以通过反射来实例化公有或私有的构造
package cn.lsl.reflect;
public class Person {
private Person(String ss){
//this.name = ss;
System.out.println("init......>>:"+ss);
}
}
package cn.lsl.reflect;
import java.lang.reflect.Constructor;
import org.junit.Test;
public class ReflectTest {
public ReflectTest(){
System.out.println("init......");
}
// @Test
// public void testPerson() throws Exception{
获得有参构造(声明为public)
// Class cls = Class.forName("cn.lsl.reflect.Person");
// Class strCls = String.class;
// Constructor c = cls.getConstructor(strCls); // 获得有参的构造,里面的参数接收的是一个Class对象
// Object o = c.newInstance("AB");
// }
@Test
public void testPerson() throws Exception{
// 获得有参私有构造
Class cls = Class.forName("cn.lsl.reflect.Person");
Class strCls = String.class;
Constructor c = cls.getDeclaredConstructor(strCls);// 获得有参的构造,里面的参数接收的是一个Class对象
c.setAccessible(true); //打开访问权限,即可以访问私有的方法
Object o = c.newInstance("jack");
}
}
4.通过反射获取类的私有属性
package cn.lsl.reflect;
public class Person {
private String name ;
private Person(String ss){
//this.name = ss;
System.out.println("init......>>:"+ss);
}
public String toString(){
return "A Person......" +name;
}
}
package cn.lsl.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import org.junit.Test;
public class ReflectTest {
public ReflectTest(){
System.out.println("init......");
}
@Test
public void testPerson() throws Exception{
// 获得有参私有构造
Class cls = Class.forName("cn.lsl.reflect.Person");
Class strCls = String.class;
Constructor c = cls.getDeclaredConstructor(strCls);// 获得有参的构造,里面的参数接收的是一个Class对象
c.setAccessible(true);
Object o = c.newInstance("jack");
//System.out.println(">>>:"+o);
//获得私有属性
Field f = cls.getDeclaredField("name");
f.setAccessible(true);
f.set(o, "Rose");
System.out.println(">>>:"+o);
}
}
5.分析一个类中有多少方法
package cn.lsl.reflect;
public class Person {
private String name ;
private Person(String ss){
//this.name = ss;
System.out.println("init......>>:"+ss);
}
public String toString(){
return "A Person......" +name;
}
public static void aa(){
System.out.println("OKOKOK");
}
}
package cn.lsl.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.junit.Test;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
public class ReflectTest {
public ReflectTest(){
System.out.println("init......");
}
@Test
public void any() throws Exception{
//分析一个类中有多少方法
Class cls = Class.forName("cn.lsl.reflect.Person");
Method[] mm = cls.getMethods();
for(Method m : mm){
System.out.println(">>:"+m.getName());
}
}
}
输出
init......
>>:aa
>>:toString
>>:getClass
>>:hashCode
>>:equals
>>:notify
>>:notifyAll
>>:wait
>>:wait
>>:wait
6.PropertyDescriptor来操作JavaBean
package cn.lsl.bean;
/**
* JavaBean的条件
* 1、拥有公开的构造
* 2、拥有setter/getter方法
*/
public class Car {
private Address address = new Address();
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
private String name;
private String no;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "name:"+getName()+",no:"+getNo()+",age:"+getAge()+",Address:"+getAddress();
}
}
package cn.lsl.bean;
public class Address {
private String city;
private String zipcode;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
@Override
public String toString() {
return "city:"+getCity()+",zipo:"+getZipcode();
}
}
package cn.lsl.bean;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws Exception {
Class cls = Class.forName("cn.lsl.bean.Car");
Object o = cls.newInstance();
// 使用PropertyDescriptor操作JavaBean
PropertyDescriptor p = new PropertyDescriptor("name", cls);
Method m = p.getWriteMethod();
m.invoke(o, "Hello");
//
PropertyDescriptor p1 = new PropertyDescriptor("no", cls);
Method m1 = p1.getWriteMethod();
m1.invoke(o, "A888");
//
PropertyDescriptor p2 = new PropertyDescriptor("age", cls);
Method m2 = p2.getWriteMethod();
m2.invoke(o, 89);
//
System.out.println(o);
}
}
7.使用BeanUtils操作JavaBea
package cn.lsl.bean;
import org.apache.commons.beanutils.BeanUtils;
public class Main {
public static void main(String[] args) throws Exception {
Class cls = Class.forName("cn.lsl.bean.Car");
Object o = cls.newInstance();
// 使用BeanUtils操作JavaBean
BeanUtils.setProperty(o, "name", "Beaz");
BeanUtils.setProperty(o, "no", "999");
BeanUtils.setProperty(o, "age", "90");
System.out.println(">>:"+o);
}
}
8.可以使用BeanUtils实现级联操作
package cn.lsl.bean;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
public class Main {
public static void main(String[] args) throws Exception {
Class cls = Class.forName("cn.lsl.bean.Car");
Object o = cls.newInstance();
// 使用BeanUtils操作JavaBean
BeanUtils.setProperty(o, "name", "Beaz");
BeanUtils.setProperty(o, "no", "999");
BeanUtils.setProperty(o, "age", "90");
级联操作
BeanUtils.setProperty(o, "address.city", "BJ");
BeanUtils.setProperty(o, "address.zipcode", "310001");
System.out.println(">>:"+o);
//获取属性
String name = BeanUtils.getProperty(o, "name");
System.out.println(name);
}
9.BeanUtils将Map属性自动放到Bean中。(可以操作成功的原则-Map的key必须要与Bean的属性一致。)
package cn.lsl.bean;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) throws Exception {
Class cls = Class.forName("cn.lsl.bean.Car");
Object o = cls.newInstance();
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "Beaz");
map.put("no", "999");
map.put("age", "90");
map.put("address.city", "BJ");
map.put("address.zipcode", "3526376374");
BeanUtils.populate(o, map);
System.out.println(">>:"+o);
}
}
10.自定义范型
应用场景:使用自定义范型颠倒任意数组
package cn.lsl;
/**
* 自定义范型
*/
public class TestG {
public static void main(String[] args) {
// 交换两个数
// String[] a = {"aa", "bb"};
// chg(a);
// for(String s : a){
// System.out.println(s);
// }
// System.out.println("----------");
// Integer[] in = {2, 5};
// chg(in);
// for(Integer s : in){
// System.out.println(s);
// }
String[] a = new String[]{"aa", "bb", "cc", "dd"};
chg(a);
for(String s : a){
System.out.println(s);
}
System.out.println("!!!!!!!!");
Integer[] in = {2,3,4,5,6,7};
chg(in);
for(Integer i : in)
System.out.println(i);
}
// 交换两个数
// public static String[] chg(String[] ss) {
// String tmp = ss[0];
// ss[0] = ss[1];
// ss[1] = tmp;
// return ss;
// }
// //自定义范型交换两个数
// public static <T> T[] chg(T[] ss) {
// T tmp = ss[0];
// ss[0] = ss[1];
// ss[1] = tmp;
// return ss;
// }
//自定义范型倒叙输出数组
public static <T> T[] chg(T[] ss){
//使用while循环
// int start = 0;
// int end = ss.length-1;
// while(true){
// if(start>=end){
// break;
// }
// T tmp = ss[start];
// ss[start] = ss[end];
// ss[end] = tmp;
// start++;
// end--;
// }
// return ss;
// 使用for循环
for(int i=0; i<ss.length/2;i++){
T tmp = ss[i];
ss[i] = ss[ss.length-1-i];
ss[ss.length-1-i] = tmp;
}
return ss;
}
}
11.注解
注解起到标识做用。比如Junit的@Test注解。Junit会在运行时检查方法上是否存在此注解,如果存在,就通过反射来运行你的方法。
12.自定义注解
注解是一个接口,语法如下:
public @interface SomeAnnotation(){}
例如:以下自定义一个注解:
public @interface MyTest(){ }
应用实例:书写一个注解类@MyTest,它的使用类似于Junit添加@Test即可运行的测试类。
package cn.lsl.mytest;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface JunitTest {
}
package cn.lsl.mytest;
import java.lang.reflect.Method;
import java.util.Scanner;
public class MainTest {
public static void main(String[] args)throws Exception{
Scanner sc = new Scanner(System.in);
System.out.println("请你 输入要测的类:");
String str = sc.nextLine();
Class cls = Class.forName(str);
Object o = cls.newInstance();
Method[] ms = cls.getMethods();
for(Method m : ms){
//判断某个方法是否包含注解
boolean boo = m.isAnnotationPresent(JunitTest.class);
if(boo){
m.invoke(o); //如果存在这个注解,我就执行它
}
}
System.out.println("over.......");
}
}
要被测试的类
package cn.lsl.mytest;
public class Car {
@JunitTest
public void aa(){
System.out.println("aaaaa");
}
public void bb(){
System.out.println("bbbbb");
}
}
package cn.lsl.mytest;
public class Person {
@JunitTest
public void sayHi1(){
System.out.println("Hi Hello..11111...");
}
@JunitTest
public void sayHi2(){
System.out.println("Hi Hello..22222...");
}
@JunitTest
public void sayHi3(){
System.out.println("Hi Hello..33333...");
}
}