What is the difference of the anonymous internal class directly call the external class instance method in the OpenJDK and Oracle? [closed] - javac

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Today, I reviewed same Android code, and found a strange phenomenon.
It is the anonymous internal class directly called the external class instance method.
In my mind, directly calling a method is equivalent to adding this directly before the method, and this is an instance of an inner class.
According to this logic, an instance of an external class is invoked directly in the anonymous inner class, that will caused the compile ERROR.
But actually compile this application, and no problem. And the running log is normal.
Therefore, writing a simple Demo to verify the previous concept is wrong. code show as below:
public class InnerClass {
public static void main(String[] args) {
new InnerClass().process();
}
public void process() {
new Thread() {
#Override
public void run() {
System.out.println(toString("test"));
}
}.start();
}
public String toString(String string) {
return string;
}
}
In the Oracle:
In the OpenJDK:
So, What is the difference of the anonymous internal class directly call the external class instance method in the OpenJDK and Oracle?
Where can I find documentation to see these differences?
I worked hard, but did not get a clear answer.
Thanks.
P.S.
In According to my point of view
public class InnerClass {
public static void main(String[] args) {
new InnerClass().process();
}
public void process() {
new Thread() {
#Override
public void run() {
// In According to my point of view
// toString("test")
// <==>
// this.toString("test")
// and `this` is the instance of Thread
// what's the error of my view?
System.out.println(toString("test"));
}
}.start();
}
public String toString(String string) {
return string;
}
}

The problem is that
public void run() {
System.out.println(toString("test"));
}
is calling toString on the anonymous Thread subclass, and that is Thread::toString(). There is no Thread::toString(String), and the toString(String) method from the enclosing scope is not considered.
The JLS states that it will only check an enclosing / outer class for a method if there is no method with the required name in the inner class. See JLS 15.12.1:
If the form is MethodName, that is, just an Identifier, then:
If the Identifier appears in the scope of a visible method declaration
with that name (§6.3, §6.4.1), then:
If there is an enclosing type declaration of which that method is a member, let T be the innermost such type declaration. The class or
interface to search is T.
This search policy is called the "comb rule". It effectively looks for methods in a nested class's superclass hierarchy before looking
for methods in an enclosing class and its superclass hierarchy. See
§6.5.7.1 for an example.
As to why OpenJDK Java 7 accepts your test class .... if that is actually true, I'd call that a compiler bug. But it would be a general Java 7 bug not an OpenJDK specific one. The javac codebases are (AFAIK) identical for Oracle and OpenJDK releases of the same version.
Interestingly, I have a copy of Oracle Java 6, and javac from that version also calls this a compilation error as well.
$ /usr/java/jdk1.6.0_45/bin/javac InnerClass.java
InnerClass.java:10: cannot find symbol
symbol: method toString(java.lang.String)
System.out.println(toString("test"));
^
1 error
So ... maybe ... you should rerun your OpenJDK Java 7 test, and make sure you are compiling the same source code!

Related

Dart - implementing a class method with argument as implemented class

I am developing external library. Assume I have different implementations of logger class, I create abstract class ILogger which those classes can then implement.
I also have various implementations of log objects that I want to adhere to ILog abstract class so I expose it as well.
The problem is when my ILogger uses ILog as argument to one of its methods. I would assume that any of my implemented logger classes (that implement ILogger) would accept any arguments that are log classes (which implement ILog).
See my constrained example below:
abstract class ILog {
const LogImpl({required this.id});
final String id;
}
class Log implements ILog {
const Log({required this.id});
final String id;
}
abstract class ILogger {
void writeLog({
required LogImpl log,
required bool persist,
});
}
class Logger implements ILogger {
void writeLog({
required Log log,
required bool persist,
}) {
print('writing $log with persistence? $persist');
}
}
void main() {
final logger = Logger();
final log = Log(id: 'abcd-1234');
logger.writeLog(log: log, persist: true)
}
For this I get error:
Error: The parameter 'log' of the method 'Logger.writeLog' has type 'Log', which does not match the corresponding type, 'ILog', in the overridden method, 'ILogger.writeLog'.
Is there a way to solve this without resorting to applying generics?
The reason why my log object ILog needs to be abstract class instead of regular class that is extended is technical. One of my serialization libraries uses source code annotation which means that this annotation cannot be part of the library (because the annotation might be different for different applications).
The program doesn't compile because it's not sound.
Dart, and object oriented programming in general, is based around subtype substitutability. If your code works with an instance of a type, it works with an instance of a subtype too - the subtype can substitute for the supertype.
The Logger's writeLog method is not a valid override of the ILogger's writeLog method. The latter accepts an ILog as argument, and for the subtype to be able to substitute for that, it needs to accept an ILog too. However, it only accepts a Log, which is a subtype, and not any implementation of ILog.
One alternative is to admit that what you are writing is unsound, and tell the compiler to accept it anyway:
class Logger implements ILogger {
void writeLog({
required covariant Log log,
required bool persist,
}) {
print('writing $log with persistence? $persist');
}
}
Here the covariant tells the compiler that you know that Log does not satisfy the superclass parameter type of ILog, but it's OK. You know what you're doing, and no-one will ever call this function with something which isn't a proper Log. (And if they do anyway, it'll throw an error).
The other alternative, which is what I'd probably recommend, is to parameterize your classes on the Log it uses:
abstract class ILogger<L extends ILog> {
void writeLog({
required L log,
required bool persist,
});
}
class Logger implements ILogger<Log> {
void writeLog({
required Log log,
required bool persist,
}) {
print('writing $log with persistence? $persist');
}
}
With that, the Logger doesn't have to substitute for all ILoggers, only for ILogger<Log>, and it can do that soundly.
(Well, as soundly as the inherently unsound covariant generics allow, but the program will compile, and throw if you ever pass something which isn't a Log instance.)
In both cases the compiler will know that the argument to a Logger must be a Log. In both cases, you can fool the program by casting the Logger to the supertype ILogger/ILogger<ILog>, and then pass in an ILog to writeLog, but it takes at least a little effort to circumvent the type system.

Should subclasses inherit private mixin variables in Dart?

Should I get the following error:
class.dart:11:11: Error: The getter '_privateID' isn't defined for the class 'Y'.
- 'Y' is from 'class.dart'.
Try correcting the name to the name of an existing getter, or defining a getter or field named '_privateID'.
From the following code?
mixin.dart:
class Mixin {
static int _nextID = 0;
int publicID = _nextID++; // I only need one of these lines
int _privateID = _nextID++; // but this variable is inaccessible
}
class.dart:
import 'mixin.dart';
class X with Mixin {
void run() {
print(publicID); // no error here
}
}
class Y with Mixin {
void run() {
print(_privateID); // Error: _privateID not defined
}
}
void main() {
Y().run();
}
Or is this a bug? If it's not a bug, I'd like to understand why this behavior is reasonable.
When I instead define the mixin in the same file as the above classes, I get no error.
(Dart SDK 2.4.1.)
It is not a bug.
The private field is inherited, but you cannot access it because its name is private to a different library.
Dart's notion of "privacy" is library private names.
The name _privateID in the mixin.dart library introduces a library private name. This name is special in that it can only be written inside the same library.
If someone writes _privateID in a different library, it is a different name, one unique to that library instead.
It is as if private names includes the library URI of the library it is written in, so what you really declare is a name _privateID#mixin.dart.
When you try to read that field in class.dart, you write ._privateID, but because it is in a different library, what you really write is ._privateID#class.dart, a completely different name, and the classs does not have any declarations with that name.
So, if one class needs to access a private member of another class (or mixin, or anything), then the two needs to be declared in the same library, because otherwise they cannot even write the name of that variable.
That is why the code works if you write the mixin in the same library.
If you want to move the mixin to a separate file, but not necessarily a separate library, you can use a part file.

Use environment variable in Cakephp 2 database.php [duplicate]

This question already has answers here:
PHP Error : Fatal error: Constant expression contains invalid operations
(5 answers)
Closed 4 years ago.
I have the following code, where I get the error "PHP Fatal Error: Constant expression contains invalid operations". It works fine when I define the variable in the constructor. I am using Laravel framework.
<?php
namespace App;
class Amazon
{
protected $serviceURL = config('api.amazon.service_url');
public function __construct()
{
}
}
I have seen this question: PHP Error : Fatal error: Constant expression contains invalid operations
But my code does not declare anything as static, so that did not answer my question.
As described here
Class member variables are called "properties". You may also see them referred to using other terms such as "attributes" or "fields", but for the purposes of this reference we will use "properties". They are defined by using one of the keywords public, protected, or private, followed by a normal variable declaration. This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.
The only way you can make this work is :-
<?php
namespace App;
class Amazon
{
protected $serviceURL;
public function __construct()
{
$this->serviceURL = config('api.amazon.service_url');
}
}
Initializing class properties is not allowed this way. You must move the initialization into the constructor.
Another working alternative I used is with boot( ) with Laravel Eloquent:
<?php
namespace App;
class Amazon {
protected $serviceURL;
protected static function boot()
{
parent::boot();
static::creating(function ($model){
$model->serviceURL = config('api.amazon.service_url');
});
} }

Resolving a type without registering first - prism 4 and Untiy

First of all I would like to remark I am new with the concept of prism, DI and containers. I am looking on one of the code samples provided with the Prism Library:
The code simply injects a view with the "Hello World" string (in a TextBlock element) to a region in the shell.
When the application starts-up, it creates a new BootStrapper instance, which creates and initializes the shell:
public class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<Shell>();
}
protected override void InitializeShell()
{
base.InitializeShell();
Application.Current.RootVisual = (UIElement)this.Shell;
}
protected override void ConfigureModuleCatalog()
{
base.ConfigureModuleCatalog();
ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;
moduleCatalog.AddModule(typeof(HelloWorldModule.HelloWorldModule));
}
}
My question refers to the method CreateShell(). I couldnt find nowhere in the supplied code (including not in a configuration file or any xaml file...) where do they register the type Shell, and even if it was registered - the supplies Shell class doesnt implement any interface... what is the meaning of resolving a specific type?
the Shell implementation:
public partial class Shell : UserControl
{
public Shell()
{
InitializeComponent();
}
}
This looks like a magic to me, so I tried to create my own type (MyType) and resolve it the same way:
Container.Resolve<MyType>();
By setting a breakepoint inside MyType constructor, I saw that it DID resolved MyType. Can somebody please explain to me how does it work?
These couple of threads should answer your question:
http://compositewpf.codeplex.com/Thread/View.aspx?ThreadId=230051
Does unity just make clasess with out needing anything registered?
Additionally, if you are eager to get more detail into how Unity can do this, simple download Unity 2.0 and open the source code that is provided with the installer.
I hope this helps.
Thanks,
Damian
You do not need to register a type you want to resolve. You need to register the dependencies of a type, that you want to resolve. In this case, the Shell doesn't need any dependencies, so you can resolve it simply. But for an example (not really), if your shell getting an interface IService as a parameter, then you must register IService, before you resolve Shell.
Otherwise you will get Dependency Resolution Failed Exception. In Prism 4.1 it will be swallowed silently due to TryResolve.

Error "More than one matching bindings are available" when using Ninject.Web.Mvc 2.0 and ASP.NET MVC 1.0

Recently I've switched to Ninject 2.0 release and started getting the following error:
Error occured: Error activating SomeController
More than one matching bindings are available.
Activation path:
1) Request for SomeController
Suggestions:
1) Ensure that you have defined a binding for SomeController only once.
However, I'm unable to find certain reproduction path. Sometimes it occurs, sometimes it does not.
I'm using NinjectHttpApplication for automatic controllers injection. Controllers are defined in separate assembly:
public class App : NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
INinjectModule[] modules = new INinjectModule[] {
new MiscModule(),
new ProvidersModule(),
new RepositoryModule(),
new ServiceModule()
};
return new StandardKernel(modules);
}
protected override void OnApplicationStarted()
{
RegisterRoutes(RouteTable.Routes);
RegisterAllControllersIn("Sample.Mvc");
base.OnApplicationStarted();
}
/* ............. */
}
Maybe someone is familiar with this error.
Any advice?
I finally figured this issue out recently. Apparently, the NinjectHttpApplication.RegisterAllControllersIn() function doesn't do all of the proper bindings needed. It binds your concrete controller implementations to IController requests. For example, if you have a controller class called SampleMvcController, which inherits from System.Web.Mvc.Controller. It would do the following named binding during application start:
kernel.Bind<IController>().To(SampleMvcController).InTransientScope().Named("SampleMvc");
But when debugging the NinjectControllerFactory, I find that request are being made for the Ninject Kernel to return an object for the class "SampleMvcController", not for a concrete implementation of IController, using the named binding of "SampleMvc".
Because of this, when the first web request that involves the SampleMvcController is made, it creates a binding of SampleMvcController to itself. This is not thread safe though. So if you have several web requests being made at once, the bindings can potentially happen more than once, and now you are left with this error for having multiple bindings for the SampleMvcController.
You can verify this by quickly refreshing an MVC URL, right after causing your web application to restart.
The fix:
The simplest way to fix this issue is to create a new NinjectModule for your controller bindings, and to load this module during application start. Within this module, you self bind each of your defined controllers, like so:
class ControllerModule : StandardModule {
public override Load() {
Bind<SampleMvcController>().ToSelf();
Bind<AnotherMvcController>().ToSelf();
}
}
But if you don't mind changing the Ninject source code, you can modify the RegisterAllControllersIn() function to self bind each controller it comes across.
I have been dealing with this problem for months. I tried so many options but was unable to come to a solution. I knew that it was a threading problem because it would only occur when there was a heavy load on my site. Just recently a bug was reported and fixed in the ninject source code that solves this problem.
Here is a reference to the issue. It was fixed in build 2.1.0.70 of the Ninject source. The key change was in KernelBase.cs by removing the line
context.Plan = planner.GetPlan(service);
and replacing it with
lock (planner)
{
context.Plan = planner.GetPlan(service);
}
To use this new build with MVC you will need to get the latest build of Ninject then get the latest build of ninject.web.mvc. Build ninject.web.mvc with the new Ninject build.
I have been using this new build for about a week with a heavy load and no problems. That is the longest it has gone without a problem so I would consider this to be a solution.
Are you sure you really are creating a single completely new Kernel from scratch in your OnApplicationStarted every time it's invoked ? If you're not and you're actually creating it once but potentially running the registration bit twice. Remember that you're not guaranteed to only ever have one App class instantiated ever within a given AppDomain.
My answer was a bit more obvious.
I had declared the binding for one of my controllers more than once during refactor of my code.
I added this to my global.ascx.cs file:
public void RegisterAllControllersInFix(Assembly assembly)
{
RegisterAllControllersInFix(assembly, GetControllerName);
}
public void RegisterAllControllersInFix(Assembly assembly, Func<Type, string> namingConvention)
{
foreach (Type type in assembly.GetExportedTypes().Where(IsController))
Kernel.Bind(type).ToSelf();
}
private static bool IsController(Type type)
{
return typeof(IController).IsAssignableFrom(type) && type.IsPublic && !type.IsAbstract && !type.IsInterface;
}
private static string GetControllerName(Type type)
{
string name = type.Name.ToLowerInvariant();
if (name.EndsWith("controller"))
name = name.Substring(0, name.IndexOf("controller"));
return name;
}
Then called it from my OnApplicationStarted() method as follows:
RegisterAllControllersIn(Assembly.GetExecutingAssembly());
RegisterAllControllersInFix(Assembly.GetExecutingAssembly());
Difficult to know whether this fixed it though because it's so intermittent.

Resources