IDEA的使用


  IDEA是由jetbrains开发的Java开发工具,该公司旗下还有如下产品:

  • WebStorm:用于开发JavaScript、HTML5、CSS3等前端。
  • PyCharm:用于开发Python。
  • PhpStorm:用于开发PHP。
  • RubyMine:用于开发Ruby/Rails。

一、IDEA基本界面介绍

1.1HelloWorld的编写

在这里插入图片描述

  • Create New Project:创建一个新的工程。
  • Import Project:导入一个现有的工程。
  • Open:打开一个已有工程。比如:可以打开 Eclipse 项目。
  • Check out from Version Control:可以通过服务器上的项目地址 check out Github 上面项目或其他 Git 托管服务器上的项目。

在这里插入图片描述
  点击创建即可:
在这里插入图片描述
在SRC文件夹下创建软件包:

在这里插入图片描述

在软件包中创建HelloWorld类,并编写:

package com.java.Demo;

public class HelloWorld {
    public static void main(String[] args){
        System.out.println("Hello World");
    }
}

二、工程与模块管理

2.1IDEA项目结构

在这里插入图片描述
在这里插入图片描述
  即,在使用IDEA编写代码时并不会将java文件直接编写在项目(project)下,而是将项目划分为不同的模块(module)以实现不同的功能,而不同的模块下又创建不同的软件包(package)存放实现功能的具体java代码。

在这里插入图片描述

层级关系

project(工程)->module(模块)->package(包)->类

具体的有:

  • 一个project可创建多个module
  • 一个module可创建多个package
  • 一个package可创建多个class

例:创建一个项目
在这里插入图片描述

  可以在项目下新建module(一个项目至少有一个模块,所以创建一个项目的过程就是创建一个模块的过程),module可以选择自己的语言、构建系统、JDK,也可使用当前项目默认的配置。

2.2项目结构详解

  以下内容以标准的maven目录作为参考。
maven项目基本结构
在这里插入图片描述

2.2.1项目设置:项目

在这里插入图片描述

  • 名称:项目的名称。
  • SDK:当前项目使用的软件工具包(即为JDK)。
  • 语言级别:用于指定项目所用语言的版本和特性,会影响IDEA的语法检查、自动补全等功能,确保能充分利用语言新特性,且避免使用不兼容的语法或功能。目前使用最多的是JDK8,若选择JDK8以前的版本,代码中有基于Lambda的语法将会报错。

在这里插入图片描述

  • 编译器输出:源程序编译后形成字节码文件的存储位置。

注意,idea项目默认编译输出到out文件夹,而maven项目则默认输出到target文件夹,故而此处与普通的java项目不同,不存在out文件夹。target目录包含classes(源代码字节码文件夹)、test-classes(测试文件字节码文件夹)与generated-sources(存放 Maven 构建过程中自动生成的源代码文件,这些文件通常是由代码生成工具或插件自动生成的,而不是由开发者手动编写的)。

2.2.2项目设置:模块

1.源

在这里插入图片描述

  • 源代码:当除项目的src目录外还有其他一些特别的目录需要作为可编译的目录,就需要对该目录进行标注,注意,只有被标记为源代码、测试的目录才可新建Java类和软件包。
  • 测试:标注可编译的单元测试目录。
  • 资源:存放源代码运行所用的资源文件,如配置文件、前端页面等,资源文件会被编译到输出目录下。
  • 测试资源:存放测试单元代码运行所用的资源文件。
  • 排除的:编译文件(字节码文件)的输出路径。

2.路径
在这里插入图片描述

  • 继承项目编译输出路径:选择后,当前模块的编译输出路径就会继承项目结构-项目-编译输出所给的路径,此处勾选后即会将编译结果输出到out文件夹中。如下图,此时target不再包含classes(源代码字节码文件夹)与test-classes(测试代码字节码文件夹),而是以普通java项目的形式输出到out文件夹中。

在这里插入图片描述

  • 使用模块编译输出目录:使用模块自己的编译输出目录存放字节码文件,此处包含classes与test-classes两种目录。
  • 排除输出目录:
  • javaDoc:
  • 外部注释:

2.2.3项目设置:库

在这里插入图片描述
  用来存放项目级依赖,即可将整个项目所用的依赖添加到此处管理,可灵活选择其所作用的模块。对于一个多模块的项目来讲,建议项目使用的所有Jar包都放在这里统一管理,模块要使用时直接按需选择即可,而不需要自己再单独添加。

2.2.4项目设置:Facet

在这里插入图片描述
  能看到项目的每个模块使用的框架、语言等情况,并且还可以对它们进行配置。常用的如Spring、Hibernate框架,可以通过Facet的自动探测功能,自动将模块添加到Facet中进行管理。

2.2.5项目设置:工件

在这里插入图片描述
  可用于实现使用IDEA进行打包的功能,流程如下:
在这里插入图片描述
在这里插入图片描述
获得清单文件MANIFEST.MF:

Manifest-Version: 1.0
Main-Class: org.example.Main

在这里插入图片描述
  选择构建-构建工件即可得到相应java包:
在这里插入图片描述
  打开终端即可运行该jar包:

PS C:\Users\28591\IDEA\myProjects\demoProject1\out\artifacts\demoProject1_jar> java -jar demoProject1.jar
Hello and welcome!i = 1
i = 2
i = 3
i = 4
i = 5

2.2.6平台设置:SDK

项目结构->SDK

  SDK(Software Development Kit,软件工具包),在此处保存的即为Java软件开发工具包(JDK):

在这里插入图片描述
注意:

  • IntelliJ IDEA是JVM平台IDEA,不仅仅支持Java还有其它语言如Kotlin,所以写成SDK而非JDK。
  • SDK并不能决定语言等级,如使用JDK11,但仍可将语言等级调为8来编译运行。

2.2.7平台设置:全局库

2.3常见项目结构

2.4.1Web项目结构

在这里插入图片描述

三、断点调试

  编好的程序在执行过程中发生错误时,可以借助程序调试来查找错误,Debug的调试步骤如下:

  • 添加断点
  • 启动调试
  • 单步执行
  • 观察变量和执行流程,找到并解决问题

debug的启动方式为:
在这里插入图片描述

  四种断点类型:
在这里插入图片描述

3.1debug操作界面简介

在这里插入图片描述

在这里插入图片描述

  • 显示执行点:点击后光标将跳转到当前正在执行(或者说是将要执行)的代码行。
  • 步过:继续向下执行代码行,不会进入方法内部。对于有输出语句的代码,可在控制台线程与变量的右边)中查看。
  • 步入:继续向下执行代码行,若会进入自己定义的方法、构造器等的内部(非自行定义就不会进入)。
  • 强制步入:继续向下执行代码行,若代码行中有方法、构造器等,无论是自己定义还是jar包当中,都会进入内部。
  • 智能步入:当前行有多个方法同时被执行,IDEA 将会询​​问你要进入哪个方法。
  • 步出:从步入的方法内执行完该方法,然后退出到方法调用处。
  • 单步跳出代码块:运行完当前代码块所有代码并退出。
  • 运行到光标处:运行到当前光标所在的位置,会遵循断点和其他调试停止点的规则,如果在执行过程中遇到了断点,程序会在那里暂停执行。
  • 强制运行到光标:运行到当前光标所在的位置,而不管是否有断点或者其他调试停止点。
  • 对表达式求值:在调试的时可以查看某个变量的值,也可以计算某个表达式的值,甚至还可以写一串代码并求值,分别对应两种不同的模式。

模式一(表达式模式):可用于从数据库读取数据后对变量数据进行查看等场景。
在这里插入图片描述
模式二(代码片段模式):只能写代码片段,不能自定义方法。
在这里插入图片描述

  • 恢复程序运行:恢复程序的运行,直到运行到下一个断点处停止运行。
  • 重新运行:重新进行debug。
  • 停止:退出debug模式。
  • 暂停程序:暂停程序的运行,并启用debug模式。一般恢复程序运行后使用,会立即停止运行并debug(程序运行很快的话,很难有机会使用)。
  • 查看断点:查看当前设置的所有断点及其信息。
  • 忽略断点:所有断点图标变为白色(若在debug前使用,则会使debug模式失效,改为程序的正常执行),使其不再起作用,可在断点处右键,使其再次生效。

示例

package org.example;

public class debug01 {
    public static void main(String[] args) {
        int[] arr1=new int[]{1,2,3,4,5};
        System.out.println(arr1);
        char[] arr2=new char[]{'a','b','c'};
        System.out.println(arr2);
    }
}

在这里插入图片描述
  在断点一处强制步入得到函数:

    public void println(Object x) {
        String s = String.valueOf(x);
        if (getClass() == PrintStream.class) {
            // need to apply String.valueOf again since first invocation
            // might return null
            writeln(String.valueOf(s));
        } else {
            synchronized (this) {
                print(s);
                newLine();
            }
        }
    }

  在断点二处强制步入得到函数:

    public void println(char[] x) {
        if (getClass() == PrintStream.class) {
            writeln(x);
        } else {
            synchronized (this) {
                print(x);
                newLine();
            }
        }
    }

可见,虽然代码中都是使用了System.out.println()函数,但在实际执行时发生了函数重载。

3.2行断点

  可作用在任何一行代码上,图标为红色圆形。当程序执行到设置断点的行时将会被触发。

package org.example;
public class debug01 {
    public static void main(String[] args) {
        //1.
        int m=10;
        int n=20;
        System.out.println("m="+m+",n="+n);
        swap(m,n);
        System.out.println("m="+m+",n="+n);
    }
    public static void swap(int m, int n) {
        int temp=m;
        m=n;
        n=temp;
    }
}

  由于Java是值传递方式,故而swap()无法正确交换m与n的值,运行结果如下:

m=10,n=20
m=10,n=20

  给int n=20;swap(m,n);打上断点,并对程序进行调试(直接运行时断点并不会发生作用):
在这里插入图片描述
  注意,此处的m与n是swap函数栈帧当中的变量(临时变量),但main函数栈帧当中的m与n并未发生改变,可点击main函数栈帧进行查看:
在这里插入图片描述

Java是一种值传递语言。

  行断点可设置出发的相关条件,如,在for循环中i=6时使用行断点,就可进行设置:
在这里插入图片描述
注意:

  • 条件语句的返回值应为布尔值(相当于嵌入了if判断语句)。
  • 断点不应打在for语句上,否则程序第一次中断时for循环尚未执行,此时并不存在局部变量i。

3.3方法断点

  方法断点的断点设置在方法签名上,默认当进入时断点可以被唤醒(而无需找出所有方法调用语句依次打上断点),也可以设置在方法退出时,断点也会被唤醒。多态的场景下,在父类或接口的方法上打断点,会自动调入到子类或实现类的方法。
程序代码:

package org.example;

public class debug01 {
    public static void main(String[] args) {
    }
}
class Father{
    public void test(){
        System.out.println("Father:test1");
        System.out.println("Father:test2");
    }
}
class Son extends Father{
    @Override
    public void test(){
        System.out.println("Son:test1");
        System.out.println("Son:test2");
    }
}
interface Consumer{
    void accept(String str);
}
class ConsumerImpl implements Consumer{
    @Override
    public void accept(String str) {
        System.out.println("ConsumerImpl"+str);
    }
}

案例一:在方法声明上打断点

public class debug01 {
    public static void main(String[] args) {
        Son instance=new Son();
        instance.test();
    }
}

  将方法断点打在Son类中test函数的声明上,进行调试:
在这里插入图片描述
同样可以为方法断点设置条件:
在这里插入图片描述
在勾选上方法退出时,test()函数在执行完退出时会自动打上断点并停留:
在这里插入图片描述
案例二:在父类上打断点(类的多态性)

public class debug01 {
    public static void main(String[] args) {
        Father instance = new Son();
        instance.test();
    }
}

  将方法断点打在Father类中test函数的声明上,进行调试:
在这里插入图片描述
  最终运行时的断点发生在了Son子类的test()方法上,通过此方法,在调试源码时可以直接跳转到子类的重载方法上,而不需要一个个的去找。

案例三:在接口上打断点(接口的多态性)

public class debug01 {
    public static void main(String[] args) {
        Consumer con=new ConsumerImpl();
        con.accept("atguigu");
    }
}

  将方法断点打在Consumer接口中accept函数的声明上,进行调试:
在这里插入图片描述
  最终运行时的断点发生在了实现类ConsumerImp的test()方法上,通过此方法,在调试源码时可以直接跳转到实现类的实现方法上,而不需要一个个的去找。

3.4属性断点

  在类的属性上打断点,默认对属性的修改操作进行监控,定义Person类如下:

class Person{
    private int id=1;
    private String name;
    private int age;
    public Person(){}
    {
        id=2;
    }
    public Person(int id){this.id=id;}
    public Person(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    public int getId() {return id;}
    public void setId(int id) {this.id = id;}
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public int getAge() {return age;}
    public void setAge(int age) {this.age = age;}
    @Override
    public String toString() {return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";}
}

在这里插入图片描述
  在debug之后,程序会在private int id=1;停下,这是因为int变量初值为0,此处已是对id的值进行了修改。会依次在以下语句停下:

private int id=1;
id=2;
this.id=id;

当选上字段访问后,会在toString()函数停下。

3.5异常断点

  当程序抛出相对应的异常时将会触发,程序会定位到抛出异常的语句并自动停止执行。

package org.example;

public class debug01 {
    public static void main(String[] args) {
        int m=10;
        int n=0;
        int result=m/n;
        System.out.println(result);
    }
}
//抛出异常:java.lang.ArithmeticException

在这里插入图片描述
此时再进行调试就会在抛出异常断点处停止运行:
在这里插入图片描述
示例

package org.example;

public class debug01 {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person.getName().toUpperCase());
    }
}
class Person{
    String name;
    int age;
    public Person(){}
    public Person(String name, int age) {}
    public String getName() { return this.name; }
    public int getAge() { return this.age; }
}
//报错:Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toUpperCase()" because the return value of "org.example.Person.getName()" is null at org.example.debug01.main(debug01.java:6)

  为java.lang.NullPointerException添加异常断点,此时可清楚看到变量person的属性为null:
在这里插入图片描述

3.6线程调试

  上述操作均是在主线程当中进行,且在调试时一步一步往下运行,不能发起其他请求,这是因为IDEA在Debug时默认阻塞级别是ALL,会阻塞其它线程,只有在当前调试线程走完时才会走其它线程。事实上,在设置断点时可设置断点的作用范围为当前线程,就不会影响其他线程的执行。

package org.example;

public class debug01 {
    public static void main(String[] args) {
        test("Thread1");
        test("Thread2");
    }
    public static void test(String threadName) {
        new Thread(
            ()->{
                for(int i=0;i<100;i++) {
                    System.out.println(Thread.currentThread().getName()+":"+i);
                }
            },threadName
        ).start();
    }
}

在这里插入图片描述
条件语句为:

"Thead2".equals(Thread.currentThread().getName())

在这里插入图片描述
在这里插入图片描述
  此时只有线程2被阻断运行,线程1正常执行,即断点只对线程2起作用。

3.7强制结束

package org.example;

public class debug01 {
    public static void main(String[] args) {
        System.out.println("获取请求的数据");
        System.out.println("调用写入数据库的方法");
        insert();
        System.out.println("程序结束");
    }
    private static void insert() {
        System.out.println("进入insert()方法");
        System.out.println("获取数据库连接");
        System.out.println("将数据写入数据表中");
        System.out.println("写出操作完成");
        System.out.println("断开连接");
    }
}

  在常见的数据库项目中,若调试到System.out.println("获取数据库连接");时已发现错误,不想insert()函数执行完(防止数据错误插入到数据表中),可通过强制返回按钮中断insert()函数的执行。
在这里插入图片描述
控制台输出为:

获取请求的数据
调用写入数据库的方法
进入insert()方法
获取数据库连接
程序结束

3.8自定义调试视图

package org.example;

import java.util.HashMap;

public class debug01 {
    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<>();
        map.put(1,"高铁");
        map.put(2,"网购");
        map.put(3,"支付宝");
        map.put(4,"共享单车");
        System.out.println(map);
    }
}

  将断点打在map.put(1,"高铁");处,在执行完后只能看到如下变量情况:
在这里插入图片描述

 &emps;右键进入自定义数据视图
在这里插入图片描述
  此时即可看到map中tabel数组的情况:
在这里插入图片描述

四、IDEA基本操作

4.1项目:创建空项目

在这里插入图片描述
  可通过关闭项目来关闭。
在这里插入图片描述

4.2模块的基本操作

1.创建module
在这里插入图片描述

  以上操作可用于在项目(project)当中创建模块(module),事实上,创建项目的过程就是为该项目创建第一个module的过程,故此处module的创建不再赘述。

2.模块导入操作
在这里插入图片描述

在这里插入图片描述
  此处要将左侧demoProject1项目下的org软件包导入到右侧的demo项目的当中,首先在资源管理器中打开,并将org软件包复制并粘贴到demo文件夹下,此时org软件包只显示为普通文件夹:
在这里插入图片描述
 &emps;在项目结构中导入该模块:
在这里插入图片描述
  最终得到:
在这里插入图片描述
  此时org也成为了demo项目下的一个模块。事实上,也可直接在demoProject1项目中复制org文件夹,然后在demo文件夹上粘贴,再在项目结构中修改即可:
在这里插入图片描述
3.移除module
在这里插入图片描述

  对module01模块右键点击移除模块后,module01对应的文件夹不会被删除,但不再属于Demo项目(项目结构当中也不能再查找到),并且只显示为是一个普通文件夹:
在这里插入图片描述
在这里插入图片描述

4.3软件包的基本操作

1.package的创建
在这里插入图片描述
  源代码一般放在src文件夹中,故软件包(package)一般也在src目录下建立。

2.软件包的移除
在这里插入图片描述
  与移除模块不同,此时会删除软件包所对应的文件夹。

3.package取名规范

  • 公司域名倒着写:如尚硅谷域名为www.atguigu.com,则写代码时创建软件包结构为com.atguigu。
    在这里插入图片描述

4.4IDEA基本设置说明

3.2解决引入java文件时的乱码问题

在这里插入图片描述
  在idea以外平台编写时,编码方式可能并不是UTF-8,以上图为例,编码方式为ANSI(Windows系统中对应为GBK,cmd属性当中可见),导致将文件复制到idea项目下时会出现中文乱码,解决方式为:
在这里插入图片描述
  选中需要更改编码方式的文件,对其特殊化处理即可:
在这里插入图片描述

2.4.3详细设置

如何打开详细设置

  • 29
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值