C# similarly has old warts that are discouraged now. .NET Framework is a great example (completely different from modern c#, which used to be called "dotnet core"). WPF and MAUI are also examples. Or when "dynamic" was used as a type escape hatch before the type system advanced to not need it. ASP being incompatible with ASP.NET, the list goes on.
They're just languages, there's no reason to pretend they're perfect.
Almost all of this is incorrect or comparing apples to oranges.
.net framework and .net core are runtime and standard library impl, not languages. C# is a language that can target either runtime or both. Framework is still supported today, and you can still use most modern C# language features in a project targeting it. WPF and Maui are both still supported and widely used. ASP predates .net - c# was never a supported language in it. ASP.net core has largely replaced ASP.net, but it's again a library and framework, not a language feature.
Dynamic in c# and the dlr are definitely not widely used because it's both difficult to use safely and doesn't fit well with the dominant paradigm of the language. If you're looking for STD lib warts binaryserializer would have been an excellent example.
I use it when deserializing unknown message types.
Dynamic is largely unnecessary, and it was unnecessary even when it was introduced.
ASP and ASP.NET are completely unrelated. ASP was designed to allow dynamic webpages to be written in VBScript (like CGI). This is not something you want to do in modern languages.
Unlike C# that has both delegates and lambdas, for example. Also finalizers and IDisposable.
I guess the difference is it's rarely "dangerous" or "hard to reason about" using the old features unlike what I see in the C++ list. Java replaces things with better things and momentum shifts behind them kind of naturally because the better things are objectively better.
The instanceof[0] operator is typically banned from use in application code and often frowned upon in library implementations.
0 - https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.htm...
[1] I guess you would get some push back at review time if you used auto_ptr.
Once code such as the below is rejected in a code review, the next version often submitted is an "if-else-if" ladder using `instanceof` (which is effectively the same thing).
TheReturnType r = null;
try {
DomainType1 instance = (DomainType1)obj;
r = ...
}
catch (ClassCastException ex) {}
if (r == null)
try {
DomainType2 instance = (DomainType2)obj;
r = ...
}
catch (ClassCastException ex) {}
if (r == null)
try {
DomainType3 instance = (DomainType3)obj;
r = ...
}
catch (ClassCastException ex) {}
...
And yes, I have seen the above scenario played out in a professional setting.> Never seen this being banned. Whats the reason?
Its usage encodes a priori assumptions of what a super-type could be, often expressed in an "if-else-if tree", thus making the logic doing so needlessly brittle and difficult to maintain.
Library logic sometimes needs to use this construct (I'd argue those abstractions need to be rethought however), but an application which does exhibits a failure in domain modelling IMHO.
Over-eager code analyser tools are themselves a "smell", in that you either justifiably or unjustifiably don't trust your developers, trying to make up for their real or perceived deficits with a rather dumb tool. That never goes well in my experience.
Reflection - unless you really need to do something fancy almost certainly a very bad idea in normal application code.
Other than that it’s either just limiting yourself to a specific JVM version or telling people not to use old syntax/patterns that were replaced with better options long ago.
* `synchronized` blocks
* raw types
* anonymous inner classes
* checked exceptions
as well as specific uses of otherwise fine language features:
* "AbstractX" style abstract classes when static and default interface methods suffice
* old-style POJO classes when records are a better choice
Exactly. Simplicity was an explicit design goal of Java.
Most items in your list are fine actually, including raw types and inner classes.
Regarding checked exceptions, it is unfortunate that people don't fully understand it, see here: https://mckoder.medium.com/the-achilles-heel-of-c-why-its-ex...