The Measurable Impact of Static Analysis on Student Code Quality

Introduction: The Gap Between Teaching Syntax and Teaching Quality

Most CS1 courses teach students to write code that compiles and produces correct output. Very few teach them to write code that is readable, maintainable, and free of technical debt from day one. The assumption is that quality comes later, after algorithms and data structures are mastered.

That assumption is costing departments time and money. A 2020 study at the University of Helsinki found that 43% of student submissions in a second-year software engineering course contained at least three major code smells, and the instructors spent an average of 6.4 minutes per submission on style and structure comments alone. Over a class of 300, that’s 32 hours of manual feedback on issues a static analyser could flag in seconds.

I wanted to know whether integrating static analysis into the assignment workflow actually improves the code students write — not just whether it saves graders time, but whether the feedback leads to different long-term habits. So, over two semesters at a large public university, we designed a controlled experiment with 1,150 students per semester (2,300 total) comparing a control section using traditional rubric grading against a treatment section where every submission was run through a suite of static analysis checks before the student could submit. The results are clear: static analysis feedback doesn’t just catch problems — it teaches students to avoid them.

Study Design: Two Sections, One Assignment, Two Workflows

The experiment ran in the third programming assignment of a Java-based CS1 course. The assignment — a simple command-line library inventory system — was identical for both sections. So was the rubric: 60% correctness, 20% code quality (style, naming, structure), 20% comment coverage.

Control section (n=576): Students submitted via a standard dropbox. TAs manually reviewed code quality on submission, following a checklist of ten common issues (e.g., magic numbers, long methods, missing Javadoc). Feedback was provided within 48 hours.

Treatment section (n=574): Students submitted through a custom web interface that ran an automated analysis pipeline before finalizing the submission. The pipeline used a combination of Checkstyle (version 8.44), PMD (6.39.0), and a custom source code metrics calculator that reported cyclomatic complexity per method, lines of code per class, and comment density. The student received a report within 3 seconds showing any failed checks and the current complexity score. They could revise and re-submit as many times as they wanted before the deadline. No TA feedback was provided; only the automated report.

Both sections had the same lecture content, the same textbook, and the same lab exercises. The only difference was the feedback mechanism.

Metrics Tracked Per Submission

MetricTool UsedThresholdWhat It Measures
Cyclomatic complexity per methodPMD (Modified McCabe)≤ 10Number of independent paths; high values indicate hard-to-test logic
Lines of code per methodPMD≤ 30Method length; long methods are typically doing too much
Magic number countCheckstyle0Literal numbers without named constants; reduces maintainability
Javadoc comment coverageCheckstyle≥ 80%Public methods/classes should have documentation
Naming convention violationsCheckstyle0camelCase for methods, PascalCase for classes, etc.
Code smell countPMD (custom ruleset)≤ 3Predefined smells: long parameter list, data clumps, switch statements, etc.

All final submissions were also run through Codequiry’s code-scanning API to verify plagiarism and AI-generated code detection (results were negligible in both sections — less than 2% flagged). That gave us confidence that the quality differences we observed were not due to cheating or AI assistance.

Results: The Numbers Tell Two Stories

We compared the final submissions (last revision before deadline) across both sections. The treatment section showed statistically significant improvements — at p < 0.001 — across every quality metric.

Primary Metrics: Before and After

MetricControl Section MeanTreatment Section MeanImprovement
Cyclomatic complexity (avg per method)8.36.5-22%
Lines of code per method (avg)24.118.7-22%
Magic number count (per submission)5.11.2-76%
Javadoc comment coverage54%83%+54%
Naming convention violations (per submission)4.30.6-86%
Code smell count (per submission)7.14.4-38%
Test coverage (unit tests, required part of assignment)62%80%+29%
“The 38% reduction in code smells is not just statistical noise. It suggests that students internalised the patterns flagged by the analyser and stopped repeating them in subsequent methods.” — Dr. Leila Vincent, lead course instructor

The most striking change was in the treatment section’s ability to self-correct. Students in the treatment group submitted an average of 3.4 revisions. The first revision in the pipeline typically had quality scores similar to the control section’s final submission. By the third revision, those scores had crossed into the treatment section’s final range. In other words, the feedback loop alone accounted for the entire improvement.

Secondary Finding: The “Late Surge” Effect

We also tracked the percentage of submissions that triggered at least one quality-related resubmission within 2 hours of the deadline. In the control section, that number was 23% — students were submitting hastily written code with obvious quality issues, knowing they could not go back. In the treatment section, the number was 1.8%. Students who could revise until submission used that time; those who couldn’t simply submitted whatever they had.

This suggests that static analysis feedback reduces the late-submission penalty that disproportionately affects weaker students. When the tool gives immediate, actionable feedback, nearly all students improve — not just the A-grade ones.

Discussion: Why Static Analysis Teaches Better Than Manual Feedback

The obvious objection is that the treatment section simply had more opportunities to see feedback — the automated report was instant, while the control section had to wait up to two days. To isolate the effect of immediacy, we ran a smaller follow-up with a third section where students received the same automated report, but only after final submission (no resubmission allowed). That section’s quality scores were statistically identical to the control section.

Immediacy alone does not explain the result. The key factor is actionability plus iteration. The student sees a specific rule — “Method ‘processInventory’ has a cyclomatic complexity of 18, threshold is 10” — and can immediately refactor that method. The rule is pre-defined, objective, and consistently applied. A TA’s comment, even when well-intentioned, is often vague: “This method is too complex, consider splitting it.” The student may not know what “complex” means in a measurable sense.

Static analysis quantifies quality. Once students learn to associate a numeric threshold with a subjective concept like “complexity,” they apply that mental model to future code. In the treatment section’s later assignments (not part of the study), we observed that median cyclomatic complexity remained 2 points lower than the control section, even though no static analysis feedback was given for those assignments. The skill transferred.

What About Code Review Culture?

Some educators argue that automated tools cannot replace the human judgment of a code review. That’s true for architectural decisions and design patterns. But for the basic hygiene that consumes most TA time — naming conventions, missing comments, long parameter lists — a machine is more consistent and less prone to bias. Freeing TAs from pattern-commenting means they can spend their energy on deeper design discussions.

At Codequiry’s code scanning platform, we see similar results in enterprise teams: developers who use automated quality gates catch 73% more style issues before peer review, and the reviews themselves get to the business logic faster. Education is no different.

Limitations and Honest Caveats

This study has several limitations:

  • Single assignment, single course. The effect might shrink or vanish in later assignments where novelty wears off. The transfer effect we saw is promising but requires replication across different tasks and languages.
  • No control for instructor effect. Both sections had the same lecturer, but different TAs. The control section’s TAs had slightly more experience, which should have helped the control group, but it didn’t.
  • Tool thresholds are arbitrary. We chose McCabe complexity ≤ 10 based on common practice. A different threshold might produce different learning outcomes. In retrospect, we should have tested multiple thresholds.
  • Student motivation. Some students may have been motivated by the tool’s “gamification” — seeing a number tick down. That effect is real but not necessarily bad; it still teaches the underlying concept.
  • Plagiarism and AI detection were negligible here, but in other contexts, automated quality feedback might inadvertently encourage students to copy code and then play with it to reduce complexity, rather than writing original code from scratch. We mitigated this with random code-review samples and Codequiry’s similarity checks, but it remains a risk worth monitoring.

Recommendations for Integrating Static Analysis into CS1

  1. Make thresholds visible and explain them. Don’t just tell the student “complexity too high.” Show a histogram of submitted complexity scores so they understand where their code falls relative to peers.
  2. Allow unlimited resubmissions before the deadline. The iteration loop is the learning mechanism. Removing the cap on resubmissions (even if it increases server load) has a bigger pedagogical return than any lecture on code quality.
  3. Use at least two different analysers. Checkstyle catches naming and Javadoc; PMD catches structural smells. No single tool covers both comprehensively. Combining them gives a broader view of quality.
  4. Do not skip final human review. The tool catches low-hanging fruit, but a TA should still spot-check for conceptual quality — proper abstraction, appropriate data structures, correct use of patterns. The difference between a passing and failing project at the end of CS1 is almost never about code smells; it’s about algorithmic thinking. Static analysis is a hygiene supplement, not a replacement for teaching design.
  5. Track longitudinal improvement. Store the historical metrics for each student. Show them a chart of how their cyclomatic complexity has changed over the semester. That long-term feedback reinforces the value of the skills they’re building.

Frequently Asked Questions

Does static analysis feedback increase grading time?

No. The initial setup of rules and thresholds takes an hour or two, but once running, the analysis is fully automated. In the study, TAs in the treatment section spent 78% less time on quality comments, allowing them to focus on correctness and design feedback.

Will students game the tool by simplifying code just to pass thresholds?

Some will, but that is still a learning outcome. A student who extracts a method solely to reduce cyclomatic complexity has just learned about method extraction and its effect on readability. The tool rewards structure that professional developers actually use.

Can I use static analysis with languages other than Java?

Yes. Similar tools exist for Python (pylint, flake8, radon), JavaScript (ESLint, complexity-analysis), C++ (cppcheck, clang-tidy), and many others. The same principles of immediacy and actionability apply regardless of language.

How do I avoid overwhelming students with too many rules?

Start with 5–7 high-impact checks: cyclomatic complexity, method length, magic numbers, naming conventions, comment coverage, and one structural smell (e.g., long parameter list). Add more rules in subsequent assignments as students become comfortable.