java放弃第一步
Java从零到放弃
环境搭建
下载地址https://www.jetbrains.com/idea/download/#section=windows
取消大小写敏感

添加中文语言插件

输出hello world
package com;
public class hello {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
常用的快捷键
F7步入 F8步过 F9运行到下一个断点 ALT+F8评估表达式 Ctrl + F查找字符串
双击Shift 查找任何内容,可搜索类、资源、配置项、方法等,还能搜索路径
Ctrl + N 按类名搜索类
Ctrl + F12 查看当前类结构
Ctrl + H 查看类的层次关系
Alt + F7 查找类或方法在哪被使用
基础知识
JAVA反射机制
反射的概念,就是在动态运行状态的时候,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能调用它的任意方法和属性(包括私有),即类对我们而言是完全透明的
想要使用反射机制,必须先获取到该类的字节码文件对象.class,通过字节码文件对象,都能够通过该类中的方法获取到我们想要的所有信息,每一个字节码文件也就对应着一个class类型的对象,获取字节码文件对象的三种方式:
Class c1 = Class.forName("类");
//通过Class的静态方法forName,获取一个类的字节码文件对象,此时仍处于源文件阶段
Class c2 = Person.class;
//当类被加载成.class文件时,Person类变成了.class,在获取该字节码文件对象,也是获取自己,处于字节码阶段
Class c3 = p.getClass();
//通过类的实例获取类的字节码对象,此时该类处于创建对象阶段
比如:
public class User {
private String name;
private int age;
public User(){}
public User(String name,int age){
this.name = name;
this.age = age;
}
public void test(){
System.out.println("年龄是:" + this.age + "姓名是:" + this.name);
}
}
上面是一个很基础的类,但是如果User类不是我们自己定义的,我们在外部无法看到里面有什么内容,需要引入反射机制
在java中所有东西都是对象,而User()和Student()又是Class的实例对象,得到class
public class Test {
public static void main(String[] args){
User user = new User();
//通过类名
Class c1 = User.class;
System.out.println(c1);
//通过对象
Class c2 = user.getClass();
System.out.println(c2);
//借用forName
try{
Class c3 = Class.forName("User");
System.out.println(c3);
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
}
上面的c1,c2,c3都是Class类的实例,代表的也都是User类,不仅是自定义的类,谁只是基本的基础数据类型都可以使用Class,比如
Class c1 = int.class;
Class c2 = string.class;
Class c3 = double.class;
Class c4 = void.class;
总结为获取Class的方法就是以下三种方法
- 对象名.getClass 通过对象名获取 比如上面的user.getClass
- 类名.class 通过类名获取 比如上面的User.class
- Class.forName 通过路径
获取类的方法
import java.lang.reflect.Method;
public class Print {
public static void printClassMethodMessage(Object obj){
//获取类的类类型
Class c = obj.getClass();
//获取类的名称
System.out.println("类的名称是:" + c.getName());
//获取方法信息
Method[] ms = c.getMethods();
for(int i = 0 ; i < ms.length ; i++){
//得到方法的返回值类型的类类型
Class returnType = ms[i].getReturnType();
System.out.println(returnType.getName() + " ");
//得到方法的名称
System.out.println(ms[i].getName()+"(");
//获取方法参数类型->得到的是参数列表的类型的类类型
Class[] ParamTypes = ms[i].getParameterTypes();
for(Class class1 : ParamTypes){
System.out.println(class1.getName() + ",");
}
System.out.println(")");
}
}
}
然后传一下User
public class Test {
public static void main(String[] args){
User user = new User("18",20);
Print.printClassMethodMessage(user);
}
}

反射获取类的方法
- getMethod(String name) 返回一个Method对象,name是指定的方法名,
- getMethods() 获取所有public函数 包括父类继承,返回Method[]数组
- getDeclaredMethods() 获取所有该类自己声明的方法,无论任何访问权限
- getDeclaredMethod(String name)返回一个Method对象,指定对应的声明方法
获取类的所有属性
public static void printFieldMessage(Object obj){
Class c = obj.getClass();
//Field类封装了关于成员变量的相关操作
//getFields()获取的是所有public的成员变量
//getDeclaredFields()获取的是此类自己声明的成员变量的信息 无论私有还是公有
//Field[] = c.getFields();
Field[] fs = c.getDeclaredFields();
for(Field field: fs){
// 1. 获取字段类型
Class fieldType = field.getType();
String typename = fieldType.getName();
// 2. 获取字段名称
String fieldname = field.getName();
// 3. 打印字段类型和字段名称
System.out.println(typename+" "+fieldname);
}
}

获取指定属性
public static Object printFieldMsgBySelf(Object obj){
Class c = obj.getClass();
try{
// 获取指定字段的内容
Field age_field = c.getDeclaredField("age");
// new实例化一个User类
Object object = c.newInstance();
// 使用反射机制打破封装
age_field.setAccessible(true);
// 为我们实例化的对象重新设置年龄
age_field.set(object,100);
return object;
} catch (Exception e){
e.printStackTrace();
}
return c;
}

在User里面添加了getAge函数,然后可以发现我们成功修改user的信息
- getField(String name) 返回一个名字是name的Field对象,但是要求是public
- getFields() 获取所有puclic的成员变量的信息
- getDeclaredField(String name) 获取自己声明的指定的成员变量name
获取类的构造方法
public static void printConMessage(Object obj){
Class c = obj.getClass();
//Constructor封装构造函数
// getConstructors获取所有的public的构造函数
// getDeclaredConstructors得到所有的构造函数
// 获取构造函数
Constructor[] cs = c.getDeclaredConstructors();
for(Constructor constructor : cs){
// 获取构造函数的名字
System.out.println(constructor.getName() + "(");
// 获取构造函数的参数列表
Class[] paramTypes = constructor.getParameterTypes();
for(Class c1 : paramTypes){
System.out.println(c1.getName()+",");
}
System.out.println(")");
}
}

-
getConstructor() 返回一个Constructor公共构造方法对象
-
getConstructors() 返回所有构造方法
-
getDeclaredConstructor() 返回一个Constructor对象,该对象反映此Class对象所表示的类或接口的指定构造方法
-
getDeclaredConstructors() 返回一个Constructor数组,反应此类声明的所有构造方法,包括所有类型
借助反射机制了解泛型,泛型是防止错误输入的,只是在编译阶段有效,只要绕过编译就无效了,比如下面ArrayList l1 = new ArrayList(); ArrayList<String> l2 = new ArrayList<String>();l2需要输入string类型的,而如果我们getclass,然后会发现运行期间c1和c2是一致的,又因为泛型失败,可以向list添加任意对象

浙公网安备 33010602011771号