一、反射
Class是反射的基石,这里的Class是一个类。它描述了Java程序中各个Java类。Class中包含类的各种信息,包含类的名字、访问属性、类的方法等等。并提供了方法来获得这些信息。
Person p1 =new Person(); Person p2=new Person();
Class cla1=new Class(); 这个是错误的,没有这样的构造方法。这里应该是一个字节码。
应该是Class cls1= Person.class 。
得到字节码的3种方式:
(1)、对象.getClass();
(2)、Class.forName("类名");// 其中这个方法需要抛出异常
(3)、类名.class;
只要在源程序中出现的类型都会有各自的Class实例对象。
那什么叫反射?反射就是把Java类中的各种成分映射成相应的Java类。Class中的方法返回相应的类。
1、构造方法的反射:
(1)得到某类所有的构造方法
字节码.getConstructors() 返回Constructor的数组。
(2)得到某类的指定构造方法
字节码.getConstructors(Class<>...) 返回Constructor的对象。存放参数类型,比如int.class String.class
示例:
<span style="white-space:pre"> </span>//new String(new StringBuffer("abc"));
Constructor constructor1 = String.class.getConstructor(StringBuffer.class);
String str2 = (String)constructor1.newInstance(new StringBuffer("abc"));
System.out.println(str2.charAt(2));
2、成员变量的反射:
(1)得到某类所有的public成员变量
字节码.getFields() 返回Field的数组。
(2)得到某类的指定成员变量
字节码.getDeclaredFields(String name) 返回Field的对象。存放变量名。
示例:
package com.heima.fanshe;
public class ReflectPoint {
private int x;
public int y;
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
}
package com.heima.fanshe;
import java.lang.reflect.Field;
public class ReflectTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
ReflectPoint rp=new ReflectPoint(1, 9);
//获取public的变量
Field fieldY=rp.getClass().getField("y");
//此时fieldY不是对象的变量 而是类的变量,要用它去获得变量里的值
System.out.println(fieldY.get(rp));
// 获取private的变量
Field fieldX=rp.getClass().getDeclaredField("x");
// System.out.println(fieldX.get(rp));//因为是私有的多疑会报错
//对私有字段的访问取消权限检查,暴力反射。
fieldX.setAccessible(true);
System.out.println(fieldX.get(rp));
}
}
这样就可以输出
9
1
(1)得到某类中的某一个成员方法
字节码.getMethod(“方法名 ”,参数...) 返回Method的对象。
示例:
<span style="white-space:pre"> </span>String str1 = "abc";
Method method=String.class.getMethod("charAt",int.class);
System.out.println(method.invoke(str1,2));
根据所学知识练习:
PCI.java
package com.heima.fanshe;
public interface PCI {
public void open();
public void close();
}
ShengKa.java
package com.heima.fanshe;
public class ShengKa implements PCI{
@Override
public void open() {
// TODO Auto-generated method stub
System.out.println("声卡开始工作");
}
@Override
public void close() {
// TODO Auto-generated method stub
System.out.println("声卡停止工作");
}
}
WangKa.java
package com.heima.fanshe;
public class WangKa implements PCI
{
@Override
public void open() {
// TODO Auto-generated method stub
System.out.println("网卡开始工作");
}
@Override
public void close() {
// TODO Auto-generated method stub
System.out.println("网卡停止工作");
}
}
ZhuBan.java
package com.heima.fanshe;
public class ZhuBan {
public void run(){
System.out.println("main board run...");
}
public void usePCI(PCI p){
if(p != null){
p.open();
p.close();
}
}
}
ReflectDemo.java
package com.heima.fanshe;
import java.io.*;
import java.util.Properties;
/*
* 电脑运行
*/
public class ReflectDemo
{
public static void main(String[] args) throws Exception {
ZhuBan mb = new ZhuBan();
mb.run();
//每次添加一个设备都需要修改代码传递一个新创建的对象
//mb.usePCI(new SoundCard());
//能不能不修改代码就可以完成这个动作
//不用new完成,而是只获取其class文件,在内部实现创建对象的动作。
File configFile = new File("pci.Properties");
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(configFile);
prop.load(fis);
fis.close();
for(int x = 0; x < prop.size(); x++){
String pciName = prop.getProperty("pci" + (x + 1));
Class clazz = Class.forName(pciName);//用Class去加载这个pci子类
PCI p = (PCI)clazz.newInstance();
mb.usePCI(p);
}
fis.close();
}
}
pci.Properties
运行结果:
二、正则表达式
用于对字符串的操作,这是一个规则。通过一些特定的符号来体现的。其缺点就是阅读性有点差。
使用String类中的方法进行组合也可以实现要求,但是代码过于冗余。所以就有了正则表达式的产生。
- 字符类
[abc] 是指a,b,c中的其中一个。
[^abc]是指除了abc三个之外的任意字符。
[a-zA-Z]是指所有的大小写英文字母
- 预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
- 字符
x 字符 x
\\ 反斜线字符
\0n 带有八进制值 0 的字符 n (0 <= n <= 7)
\0nn 带有八进制值 0 的字符 nn (0 <= n <= 7)
\0mnn 带有八进制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7)
\xhh 带有十六进制值 0x 的字符 hh
\uhhhh 带有十六进制值 0x 的字符 hhhh
\t 制表符 ('\u0009')
\n 新行(换行)符 ('\u000A')
\r 回车符 ('\u000D')
\f 换页符 ('\u000C')
\a 报警 (bell) 符 ('\u0007')
\e 转义符 ('\u001B')
\cx 对应于 x 的控制符
- 数量词
X? X,一次或一次也没有X* X,零次或多次X+ X,一次或多次X{n} X,恰好 n 次X{n,} X,至少 n 次X{n,m} X,至少 n 次,但是不超过 m 次
正则表达式的功能:
1、匹配 String方法中的matches方法用于匹配正则表达式。只要有一处不符合返回false。
· 2、切割 其实使用的就是String类中的split方法。
3、替换
4、获取
邮箱验证的示例:
package com.itheima;
import java.io.InputStreamReader;
import java.util.Scanner;
/**
* 验证用户输入的邮箱格式是否正确
* @author Administrator
*
*/
public class ZhengzeEmail {
/**
* @param args
*/
public static boolean matches(String Email)
{
String reg="\\w+@\\w+(\\.\\w{2,3})*\\.\\w{2,3}";
return Email.matches(reg);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner=new Scanner(System.in);
String email=scanner.nextLine();
if(matches(email))
{
System.out.println("格式正确");
}
else
{
System.out.println("格式不正确");
}
}
}
运行结果: