关于JDK中自带的类加载器:
1.什么是类加载器?
专门负责加载类的命令/工具.
ClassLoader
2.JDK中自带了3个类加载器
启动类加载器:rt.jar
扩展类加载器:ext/*.jar
应用类加载器:classpath
3.假设有这样一段代码:
String s = “abc”;
代码在开始执行之前,会将所需要类全部加载到JVM当中.
通过类加载器加载,看到以上代码类加载器会找string.class
文件,找到就加载,那么是怎么进行加载的呢?
首先通过“启动类加载器”加载。
注意:启动类加载器专门加载: C:\Program Files\Java\jdk1.8.0_ 101\jre\lib\rt.jar
rt.jar中都是JDK最核心的类库.
如果通过”启动类加载器"加载不到的时候,
会通过"扩展类加载器"加载.
注意:扩展类加载器专门加载: C:\program Flles\Java\jdk1.8.0_ 101\jre\lib\ext*.jar
如果"扩展类加载器"”没有加载到,那么
会通过应用类加载器"加载"
注意:应用类加载器专门加载: classpath 中的jar包(class文件)
4、 java中为了保证类加载的安全,使用了双亲委派机制.
优先从启动类加载器中加载,这个称为父”
父"无法加裁到,再从扩展类加载器中加载,
这个称为母"。双亲委派。如果都加载不到,
才会考虑从应用类加载器中加载。直到加载
到为止.
反射当中的Field
1、反射Student类当中所有的Field
先给出Student类
//反射属性 Filed
public class Student {
//Filed翻译为字段。其实就是属性/成员
// 4个Field ,分别采用了不同的访问控制权限修饰符
public int no;//Field对象
private String name;
protected int age;
boolean sex;
public static final double MATH_PI=3.1415926;
}
public class ReflectTest05 {
public static void main(String[] args) throws Exception {
//获取整个类
Class studentClass =Class.forName("reflect.Student");
String className=studentClass.getName();
System.out.println("完整类名:"+className);//reflect.Student
String simpleName=studentClass.getSimpleName();
System.out.println("简类名"+simpleName);//Student
//获取类中的所有的public修饰的Field
Field[] fields=studentClass.getFields();
System.out.println(fields.length);//测试数组中只有1个元素
//取出这个Field
Field f=fields[0];
//取出这个Field它的名字
String fieldName=f.getName();
System.out.println(fieldName);
//获取所有的Field
Field[] fs=studentClass.getDeclaredFields();
System.out.println(fs.length);//4
System.out.println("=============================");
//遍历
for (Field field:fs){
//获取属性的修饰符列表
int i=field.getModifiers();//返回的修饰符是一个数字,每个数字是修饰符的代号! !
String modiferString=Modifier.toString(i);
System.out.println(modiferString);
//获取属性的类型
Class fileType=field.getType();
String fName=fileType.getSimpleName();
System.out.println(fName);
//获取属性的名字
System.out.println(field.getName());
}
}
}
2、通过反射机制,反编译一个类的属性Field
public class ReflectTest06 {
public static void main(String[] args) throws Exception{
//创建这个是为了拼接字符串
StringBuilder s=new StringBuilder();
//Class studentClass=Class.forName("reflect.Student");
Class studentClass=Class.forName("java.lang.String");
s.append(Modifier.toString(studentClass.getModifiers()) +" class "+studentClass.getSimpleName()+"{\n");
Field[] fields=studentClass.getDeclaredFields();
for (Field field:fields){
s.append("\t");
s.append(Modifier.toString(field.getModifiers()));
s.append(" ");
s.append(field.getType().getSimpleName());
s.append(" ");
s.append(field.getName());
s.append(";\n");
}
s.append("}");
System.out.println(s);
}
}
3、使用反射机制怎么去访问一个对象的属性(set get)
import java.lang.reflect.Field;
public class ReflectTest07 {
public static void main(String[] args) throws Exception{
//不使用反射机制,怎么去访问一个对象的属性呢?
Student s = new Student();
//给属性赋值
s.no = 111;
//读属性值
System.out.println(s.no);
//使用反射机制怎么去访问一个对象的属性(set get)
Class studentClass=Class.forName("reflect.Student");
Object obj=studentClass.newInstance();//obj就是Student对象(底层调用无参数构造方法)
//获取no属性(根据属性的名称来获取Field)
Field noFields=studentClass.getDeclaredField("no");
//给obj这个对象的no属性赋值
/*
虽然使用了反射机制,但是三要素还是缺一不可:
要素1 :obj对象
要素2 :no属性
要素3 : 222值
*/
noFields.set(obj,222);
//读取属性的值
System.out.println(noFields.get(obj));//222
//可以访问私有的属性吗?
Field nameField=studentClass.getDeclaredField("name");
//打破封装(反射机制的缺点:打破封装,会给不法分子留下机会!!!)
//这样设置完之后,在外部也是可以访问private的。
nameField.setAccessible(true);
nameField.set(obj,"jackson");
//获取name属性的值
System.out.println(nameField.get(obj));
}
}
反射Method
先给出 UserService类
public class UserService {
/**
*
* @param name 用户名
* @param password 密码
* @return true登录成功,false登录失败
*/
public boolean login(String name,String password){
if ("admin".equals(name) && "123".equals(password)) {
return true;
}
return false;
}
public void login(int i){
}
/**
* 退出系统的方法
*/
public void logout(){
System.out.println("系统已经安全退出!");
}
}
public class ReflectTest08 {
public static void main(String[] args) throws Exception {
Class userServiceClass=Class.forName("reflect.UserService");
//获取所有的Method(包括私有的)
Method[] methods=userServiceClass.getDeclaredMethods();
System.out.println(methods.length);//2
//遍历Method
for (Method method:methods){
//获取修饰符列表
System.out.println(Modifier.toString(method.getModifiers()));
//获取方法的返回值类型
System.out.println(method.getReturnType().getSimpleName());
//获取方法名
System.out.println(method.getName());
//方法的修饰符列表(一个方法的参数列表可能会有多个)
Class[] parameterTypes =method.getParameterTypes();
for (Class parameterType :parameterTypes){
System.out.println(parameterType.getSimpleName());
}
}
}
}
1、反编译一个类的方法
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class ReflectTest09 {
public static void main(String[] args) throws Exception{
StringBuilder s=new StringBuilder();
//Class userServiceClass=Class.forName("reflect.UserService");
Class userServiceClass=Class.forName("java.lang.String");
s.append(Modifier.toString(userServiceClass.getModifiers())+"class"+userServiceClass.getSimpleName()+"{\n");
Method[] methods=userServiceClass.getDeclaredMethods();
for (Method method :methods){
s.append("\t");
s.append(Modifier.toString(method.getModifiers()));
s.append(" ");
s.append(method.getReturnType().getSimpleName());
s.append(" ");
s.append(method.getName());
s.append("(");
//参数列表
Class[] parameters=method.getParameterTypes();
for (Class parameter:parameters){
s.append(parameter.getSimpleName());
s.append(",");
}
//删除指定下标位置上的字符
s.deleteCharAt(s.length()-1);
// s.substring(0,s.length());
s.append("){}\n");
}
s.append("}");
System.out.println(s);
}
}
2、通过反射机制调用一个对象的方法
public class ReflectTest10 {
public static void main(String[] args) throws Exception {
//不使用反射机制,怎么调用方法
UserService userService=new UserService();
/*
要素分析:
要素1 :对象userService
要素2 :login方法名
要素3 :实参列表
要素4 :返回值
*/
boolean lognSuccess=userService.login("admin","123");
System.out.println(lognSuccess?"登陆成功":"登录失败");
Class userServiceClass=Class.forName("reflect.UserService");
//创建对象
Object o=userServiceClass.newInstance();
//获取Method
Method loginMethod=userServiceClass.getDeclaredMethod("login", String.class, String.class);
//Method loginMethod=userServiceClass.getDeclaredMethod("login", int.class);
//调用方法
//四要素:
/*
loginMethod 方法
obj 对象
"admin", "123” 实参
retValue 返回值
*/
Object reValue=loginMethod.invoke(o,"admin","123");
System.out.println(reValue);
}
}
反射Constructor构造方法
1、反编译一个类的Constructor构造方法。
public class ReflectTest11 {
public static void main(String[] args) throws Exception {
StringBuilder s = new StringBuilder();
//Class vipClass = Class.forName("reflect.Vip");
Class vipClass = Class.forName("java.lang.String");
s.append(Modifier.toString(vipClass.getModifiers()));
s.append(" c1ass ");
s.append(vipClass.getSimpleName());
s.append("{\n");
//拼接构造方法
Constructor[] constructors = vipClass.getDeclaredConstructors();
for(Constructor constructor : constructors) {
//public Vip(int no, String namd String birth, boolean sex) {
s.append("\t");
s.append(Modifier.toString(constructor.getModifiers()));
s.append(" ");
s.append(vipClass.getSimpleName());
s.append("(");
//拼接参数
Class[] parameterTypes = constructor.getParameterTypes();
for (Class parameterType : parameterTypes) {
s.append(parameterType.getSimpleName());
s.append(",");
}
//删除最后下标位置上的字符
if(parameterTypes.length>0){
s.deleteCharAt(s.length()-1);
}
s.append("){}\n");
}
s.append("}");
System.out.println(s);
}
}
使用反射机制创建对象
先给出Vip类
public class Vip {
int no;
String name;
String birth;
boolean sex;
public Vip() {
}
public Vip(int no, String name) {
this.no = no;
this.name = name;
}
public Vip(int no, String name, String birth) {
this.no = no;
this.name = name;
this.birth = birth;
}
public Vip(int no, String name, String birth, boolean sex) {
this.no = no;
this.name = name;
this.birth = birth;
this.sex = sex;
}
@Override
public String toString() {
return "Vip{" +
"no=" + no +
", name='" + name + '\'' +
", birth='" + birth + '\'' +
", sex=" + sex +
'}';
}
}
获取父类和父接口
public class ReflectTest13 {
public static void main(String[] args) throws Exception
{
//String举例
Class stringClass=Class.forName("java.lang.String");
//获取String的父类
Class superClass=stringClass.getSuperclass();
System.out.println(superClass.getName());
//获取String类实现的所有接口(一个类可以实现多个接口)
Class[] interfaces=stringClass.getInterfaces();
for (Class in:interfaces){
System.out.println(in.getName());
}
}
}
public class ReflectTest12 {
public static void main(String[] args) throws Exception {
//不使用反射机制怎么创建对象
Vip v1=new Vip();
Vip v2=new Vip(110,"zhangsan","2001-10-11",true);
//使用反射机制怎么创建对象
Class c = Class.forName("reflect.Vip");
//调用无参数构造方法
Object obj=c.newInstance();
System.out.println(obj);
//调用有参数的构造方法
//第一步:先获取到这个有参数的构造方法
Constructor con=c.getDeclaredConstructor(int.class,String.class,String.class,boolean.class);
//调用构造方法new对象
Object newObj=con.newInstance(111,"jackson","1990-10-11",true);
System.out.println(newObj);
//获取无参数构造方法
Constructor con2 = c.getDeclaredConstructor() ;
Object newObj2 = con2.newInstance();
System.out.println(newObj2);
}
}
资源绑定器
java.util包下提供了一个资源绑定器,便于获取属性配置文件中的内容。
使用以下这种方式的时候,属性配置文件xxx.properties必须放到类路径下。
public class ResourceBundleTest {
public static void main(String[] args) {
//资源綁定器,只能綁定xxx.properties文件。并且这个文件必须在类路径下。文件扩展名也必须是properties
//并且在写路径的时候,路径后面的扩展名不能写。
ResourceBundle bundle=ResourceBundle.getBundle("classinfo");
String className=bundle.getString("className");
System.out.println(className);
}
}